Bagaimana Anda mengubah kondisi boolean menjadi tipe integer di Java tanpa percabangan atau lompatan dalam kode byte yang dikompilasi dan kode mesin JITed [duplikat]

Dec 03 2020

Seperti dalam contoh yang diberikan di sini untuk C / C ++:

... Ini karena teknik baru yang dijelaskan dalam "BlockQuicksort: Bagaimana Kesalahan Perkiraan Cabang tidak memengaruhi Quicksort" oleh Stefan Edelkamp dan Armin Weiss. Singkatnya, kita melewati prediksi cabang dengan menggunakan buffer kecil (seluruhnya dalam cache L1) dari indeks elemen yang perlu ditukar. Kami mengisi buffer ini dengan cara bebas cabang yang cukup elegan (dalam 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);
}

bagaimana hal yang sama bisa dicapai di Jawa tanpa cabang atau lompatan?

Jawaban

WilliamRosenbloom Dec 02 2020 at 23:48

Sayangnya, ini tidak mungkin dilakukan di Jawa.

Untuk memahami alasannya, lihat tipe asli di balik tipe Java dalam JVM.

MEMPERHATIKAN:

  • intPrimitif Java ( jint) didukung oleh bilangan bulat bertanda 32-bit .
  • booleanPrimitif Java ( jboolean) didukung oleh integer 8-bit unsigned .

Alasan Anda tidak dapat melakukan cast di antara keduanya tanpa jump atau branch adalah bahwa cast harus melibatkan perbandingan yang ditandatangani-unsigned, dan perbandingan yang ditandatangani-unsigned harus melibatkan lompatan atau cabang. Jawaban atas pertanyaan ini memberikan penjelasan yang bagus tentang mengapa.

Pada dasarnya, di tingkat perangkat keras, prosesor itu sendiri tidak dapat melakukan perbandingan bertanda tangan tanpa tanda tangan dalam satu operasi. Prosesor harus melakukan perbandingan dalam hal perbandingan yang ditandatangani dan tidak ditandatangani. Ini membutuhkan pohon logika, dan karena itu juga membutuhkan lompatan atau percabangan.

TL; DR: int untuk booleankonversi tidak dapat dilakukan di Java tanpa lompatan atau percabangan di tingkat asli, karena booleantidak bertanda tangan dan intditandatangani dan oleh karena itu konversi memerlukan perbandingan bertanda-tidak-bertanda tangan.