コンパイルされたバイトコードとJITされたマシンコードを分岐またはジャンプせずに、Javaでブール条件を整数型に変換するにはどうすればよいですか[重複]

Dec 03 2020

ここに示したC / C ++の例のように:

...これは、StefanEdelkampとArminWeissによる「BlockQuicksort:ブランチの誤予測がQuicksortに影響を与えない方法」で説明されている新しい手法によるものです。つまり、スワップする必要のある要素のインデックスの小さなバッファー(完全に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では不可能です。

その理由を理解するには、JVM内のJavaタイプの背後にあるネイティブタイプを見てください。

通知:

  • Javaintプリミティブ(jint)は、32ビットの符号付き整数に支えられています。
  • Javabooleanプリミティブ(jboolean)は、8ビットの符号なし整数に支えられてます。

ジャンプまたはブランチなしで2つの間でキャストできない理由は、キャストには必ず符号付きと符号なしの比較が含まれ、符号付きと符号なしの比較には必ずジャンプまたは分岐が含まれるためです。答えこの質問は、なぜの良い説明を提供します。

基本的に、ハードウェアレベルでは、プロセッサ自体が1回の操作で符号付きと符号なしの比較を実行することはできません。プロセッサは、符号付き-符号付きおよび符号なし-符号なしの比較に関して比較を行う必要があります。これにロジックツリーが必要であるため、ジャンプまたは分岐も必要です。

TL; DR: Javaでは、ネイティブレベルでジャンプまたは分岐せずintboolean変換を行うことはできません。これbooleanは、が符号なしで符号付きでintあるため、変換には符号付きと符号なしの比較が必要なためです。