1 poin oleh GN⁺ 4 jam lalu | 1 komentar | Bagikan ke WhatsApp
  • Emulator x86-32 menghasilkan kode native melalui translasi biner untuk menjalankan kode x86-32 di prosesor lain, dan memberikan peningkatan performa besar dibanding pendekatan interpreter
  • Emulator tersebut dapat dipahami sebagai melihat x86-32 seperti bytecode, dengan struktur yang membuat emulator bekerja layaknya kompiler JIT
  • Sebuah program perlu mengalokasikan sekitar 64KB memori di stack dan menginisialisasinya; cara umumnya adalah melakukan stack probe, lalu menurunkan stack pointer dan menginisialisasi memori dengan loop kecil
  • Kompiler untuk kode itu, alih-alih membuat loop, menghasilkan 65.536 instruksi penulisan byte terpisah, dan karena tiap instruksi berukuran 4 byte, diperlukan 256KB kode untuk menginisialisasi data 64KB
  • Tim emulator menambahkan kode khusus ke translator untuk mendeteksi fungsi ini dan menggantinya dengan loop pendek yang setara

Latar belakang: emulator x86-32 dan translasi biner

  • Windows pernah menyertakan emulator prosesor x86-32 untuk sistem yang berjalan di prosesor selain x86-32
  • Tulisan aslinya tidak menyebutkan prosesor mana yang menjadi kasus ini
  • Emulator tersebut menggunakan translasi biner untuk menghasilkan kode native yang menjalankan perilaku yang setara dengan kode x86-32 asli
  • Pendekatan ini memberikan peningkatan performa yang signifikan dibanding emulasi berbasis interpreter
  • Ini bisa dipahami dengan melihat x86-32 sebagai bytecode, dan emulator sebagai kompiler JIT

Kode bermasalah: inisialisasi memori stack 64KB

  • Sebuah program perlu mengalokasikan sekitar 64KB memori di stack dan menginisialisasinya
  • Cara standarnya adalah terlebih dahulu melakukan stack probe untuk memastikan 64KB memori itu dapat digunakan
  • Setelah itu, stack pointer dikurangi sebesar 65.536, lalu memori diinisialisasi menggunakan loop kecil yang rapat

Loop unrolling kompiler yang berlebihan

  • Kompiler yang mengompilasi kode tersebut tidak menghasilkan loop untuk menginisialisasi setiap byte
  • Sebagai gantinya, loop itu dibentangkan menjadi 65.536 instruksi “tulis byte ke memori” yang terpisah
  • Setiap instruksi panjangnya 4 byte
  • Akibatnya, untuk menginisialisasi data 64KB dibutuhkan kode 256KB

Respons tim emulator

  • Tim emulator menambahkan kode khusus ke translator untuk mendeteksi fungsi ini
  • Fungsi yang terdeteksi kemudian diganti dengan loop pendek yang menjalankan perilaku setara
  • Penanganan ini tidak sekadar menerjemahkan kode program asli apa adanya, tetapi mengubah pola kode yang tidak efisien menjadi bentuk yang lebih ringkas selama emulasi

1 komentar

 
GN⁺ 4 jam lalu
Pendapat di Lobste.rs
  • Saya cukup suka komentar yang menjelaskan loop unrolling kepada Raymond Chen

    • Komentar itu mungkin ditulis bukan hanya untuk penulis blog, tetapi juga untuk pembaca umum
      Di antara orang-orang yang membaca tulisan seperti ini, tidak semuanya sudah tahu seluruh pengetahuan latar belakang, jadi banyak juga yang berterima kasih atas petunjuk untuk belajar lebih jauh
    • Saya tidak melihat komentar itu, sepertinya sudah dihapus. Meski begitu, kalau itu Raymond Chen, dia memang legenda hidup
      https://joelonsoftware.com/2004/06/…
    • Ini mengingatkan saya pada kejadian beberapa dekade lalu di Slashdot ketika seseorang mencoba menjelaskan topik Perl kepada larry@wall.org
  • Sepertinya ini terjadi di Alpha. Soalnya, sangat banyak pekerjaan yang dimasukkan ke emulator x86 untuk platform itu