¿Cómo se convierte una condición booleana en un tipo entero en Java sin una ramificación o un salto en el código de bytes compilado y el código de máquina JIT [duplicado]?

Dec 03 2020

Como en el ejemplo dado aquí para C / C ++:

... Esto se debe a una nueva técnica descrita en "BlockQuicksort: Cómo las predicciones erróneas de rama no afectan a Quicksort" por Stefan Edelkamp y Armin Weiss. En resumen, omitimos el predictor de rama utilizando pequeños búferes (completamente en la caché L1) de los índices de elementos que deben intercambiarse. Llenamos estos búferes de una manera sin ramificaciones que es bastante elegante (en 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);
}

¿Cómo se puede lograr lo mismo en Java sin una rama o un salto?

Respuestas

WilliamRosenbloom Dec 02 2020 at 23:48

Desafortunadamente, esto no es posible en Java.

Para entender por qué, eche un vistazo a los tipos nativos detrás de los tipos de Java dentro de la JVM.

DARSE CUENTA:

  • Los intprimitivos de Java ( jint) están respaldados por enteros de 32 bits con signo .
  • Los booleanprimitivos de Java ( jboolean) están respaldados por enteros sin signo de 8 bits .

La razón por la que no puede lanzar entre los dos sin un salto o una ramificación es que la transmisión implica necesariamente una comparación firmada-sin firmar, y la comparación firmada-no firmada implica necesariamente saltos o ramificaciones. La respuesta a esta pregunta proporciona una buena explicación de por qué.

Básicamente, a nivel de hardware, el procesador en sí no puede realizar una comparación con firma y sin firma en una sola operación. El procesador tiene que hacer la comparación en términos de comparaciones firmadas-firmadas y no firmadas-sin firmar. Esto requiere un árbol lógico y, por lo tanto, también requiere saltos o ramificaciones.

TL; DR: int a booleanla conversión no se puede hacer en Java sin saltos o ramificación a nivel nativo, porque booleanno está firmado y intestá firmado y por lo tanto requiere una conversión comparación firmado-sin firmar.