Comment convertir une condition booléenne en un type entier en Java sans branchement ou saut dans le code d'octet compilé et le code machine JITed [duplicate]

Dec 03 2020

Comme dans l'exemple donné ici pour C / C ++:

... Ceci est dû à une nouvelle technique décrite dans "BlockQuicksort: Comment les erreurs de branche n'affectent pas Quicksort" par Stefan Edelkamp et Armin Weiss. En bref, nous contournons le prédicteur de branche en utilisant de petits tampons (entièrement dans le cache L1) des indices des éléments qui doivent être échangés. Nous remplissons ces tampons d'une manière sans branche qui est assez élégante (en pseudocode):

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

comment peut-on réaliser la même chose en Java sans branche ni saut?

Réponses

WilliamRosenbloom Dec 02 2020 at 23:48

Malheureusement, cela n'est pas possible en Java.

Pour comprendre pourquoi, jetez un œil aux types natifs derrière les types Java dans la JVM.

REMARQUER:

  • Les intprimitives Java ( jint) sont soutenues par des entiers signés 32 bits .
  • Les booleanprimitives Java ( jboolean) sont soutenues par des entiers non signés 8 bits .

La raison pour laquelle vous ne pouvez pas effectuer de conversion entre les deux sans saut ou branche est que la conversion implique nécessairement une comparaison signée-non signée, et la comparaison signé-non signé implique nécessairement des sauts ou des branches. La réponse à cette question explique bien pourquoi.

Fondamentalement, au niveau matériel, le processeur lui-même n'est pas en mesure d'effectuer une comparaison signée-non signée en une seule opération. Le processeur doit faire la comparaison en termes de comparaisons signées et non signées non signées. Cela nécessite un arbre logique, et donc également des sauts ou des branchements.

TL; DR: int à la booleanconversion ne peut pas être fait en Java sans sauts ou de branchement au niveau natif, parce que booleannon signé, intest signé et donc une conversion nécessite une comparaison signé-signé.