Como você converte uma condição booleana em um tipo inteiro em Java sem uma ramificação ou salto no código de byte compilado e no código de máquina JITed [duplicado]

Dec 03 2020

Como no exemplo dado aqui para C / C ++:

... Isso se deve a uma nova técnica descrita em "BlockQuicksort: Como as previsões erradas do Branch não afetam o Quicksort", de Stefan Edelkamp e Armin Weiss. Resumindo, contornamos o preditor de branch usando pequenos buffers (inteiramente no cache L1) dos índices de elementos que precisam ser trocados. Preenchemos esses buffers sem ramificações, o que é bastante elegante (em pseudocódigo):

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);
}

como pode o mesmo ser alcançado em Java sem um branch ou jump?

Respostas

WilliamRosenbloom Dec 02 2020 at 23:48

Infelizmente, isso não é possível em Java.

Para entender o porquê, dê uma olhada nos tipos nativos por trás dos tipos Java na JVM.

AVISO PRÉVIO:

  • intPrimitivos Java ( jint) são apoiados por inteiros assinados de 32 bits .
  • booleanPrimitivos Java ( jboolean) são apoiados por inteiros sem sinal de 8 bits .

A razão pela qual você não pode lançar entre os dois sem um salto ou ramificação é que a conversão necessariamente envolve uma comparação assinado-não-assinado, e a comparação assinado-não-assinado necessariamente envolve saltos ou ramificações. A resposta a esta pergunta fornece uma boa explicação do porquê.

Basicamente, no nível do hardware, o próprio processador não é capaz de realizar a comparação com sinal e sem sinal em uma única operação. O processador tem que fazer a comparação em termos de comparações assinadas e não assinadas. Isso requer uma árvore lógica e, portanto, também requer saltos ou ramificações.

TL; DR: int a booleanconversão não pode ser feita em Java sem saltos ou ramificações no nível nativo, porque booleannão tem sinal e inté assinado e, portanto, uma conversão requer comparação assinado-não-assinado.