Как преобразовать логическое условие в целочисленный тип в Java без ветвления или перехода в скомпилированном байтовом коде и машинном коде JIT [дубликат]

Dec 03 2020

Как в примере, приведенном здесь для C / C ++:

... Это связано с новой техникой, описанной в статье Стефана Эделькампа и Армина Вайса в статье «BlockQuicksort: Как неверные предсказания ветвей не влияют на быструю сортировку». Короче говоря, мы обходим предсказатель ветвления, используя небольшие буферы (полностью в кэше L1) индексов элементов, которые необходимо поменять местами. Мы заполняем эти буферы без ветвей, что довольно элегантно (в псевдокоде):

buffer_num = 0; buffer_max_size = 64;
for (int i = 0; i < buffer_max_size; ++i) {
    // With branch:
    if (elements[i] < pivot) { buffer[buffer_num] = i; buffer_num++; }
    // Without:
    buffer[buffer_num] = i; buffer_num += (elements[i] < pivot);
}

как можно добиться того же в Java без перехода или перехода?

Ответы

WilliamRosenbloom Dec 02 2020 at 23:48

К сожалению, в Java это невозможно.

Чтобы понять, почему, взгляните на собственные типы, стоящие за типами Java в JVM.

ВНИМАНИЕ:

  • Java intпримитивы ( jint) опираются на 32-разрядных подписанных целых чисел.
  • booleanПримитивы Java ( jboolean) поддерживаются 8-битными целыми числами без знака .

Причина, по которой вы не можете выполнять приведение между ними без перехода или ветвления, заключается в том, что приведение обязательно включает сравнение со знаком-без знака, а сравнение со знаком-без знака обязательно включает переходы или ветвления. Ответ на этот вопрос дает хорошее объяснение того, почему.

По сути, на аппаратном уровне сам процессор не может выполнить сравнение без знака и без знака за одну операцию. Процессор должен выполнять сравнение в терминах сравнений со знаком и без знака. Это требует логического дерева и, следовательно, также требует переходов или ветвлений.

TL; DR: int для booleanпреобразования не может быть сделан в Java без скачков или разветвления на родной уровне, поскольку booleanне подписано и intподписан , и поэтому преобразование требует зарегистрировано без знака сравнения.