it-swarm-id.com

Kompiler JIT untuk C, C ++, dan sejenisnya

Apakah ada kompiler just-in-time di luar sana untuk bahasa yang dikompilasi, seperti C dan C++? (Nama pertama yang muncul di pikiran adalah Dentang dan LLVM! Tapi saya tidak berpikir mereka saat ini mendukungnya.)

Penjelasan:

Saya pikir perangkat lunak dapat mengambil manfaat dari umpan balik profil runtime dan secara agresif dioptimalkan kompilasi hotspot saat runtime, bahkan untuk bahasa yang dikompilasi-ke-mesin seperti C dan C++.

Optimalisasi yang dipandu profil melakukan pekerjaan yang serupa, tetapi dengan perbedaan JIT akan lebih fleksibel dalam lingkungan yang berbeda. Di PGO Anda menjalankan biner Anda sebelum melepaskannya. Setelah Anda merilisnya, ia tidak akan menggunakan umpan balik lingkungan/input yang dikumpulkan saat runtime. Jadi jika pola input diubah, itu adalah probe untuk penalti kinerja. Tetapi JIT bekerja dengan baik bahkan dalam kondisi seperti itu.

Namun saya pikir itu kontroversial apakah manfaat kinerja kompilasi JIT melebihi overhead sendiri.

33

[Lihat edit riwayat untuk jawaban yang sangat berbeda yang sekarang pada dasarnya sudah usang.]

Ya, ada beberapa kompiler JIT untuk C dan/atau C++.

CLing (seperti yang Anda tebak dari game) didasarkan pada Dentang/LLVM. Kerjanya seperti seorang juru bahasa. Artinya, Anda memberinya beberapa kode sumber, memberikan perintah untuk menjalankannya, dan itu berjalan. Penekanan di sini terutama pada kenyamanan dan kompilasi yang cepat, bukan optimalisasi yang maksimal. Dengan demikian, meskipun secara teknis jawaban untuk pertanyaan itu sendiri, ini tidak benar-benar sesuai dengan niat OP.

Kemungkinan lain adalah NativeJIT . Ini cocok dengan pertanyaan yang agak berbeda. Secara khusus, ia tidak menerima kode sumber C atau C++, dan kompilasi dan jalankan. Sebaliknya, ini adalah kompiler kecil yang dapat Anda kompilasi ke dalam program C++ Anda. Ia menerima ekspresi yang pada dasarnya dinyatakan sebagai EDSL di dalam program C++ Anda, dan menghasilkan kode mesin aktual dari itu, yang kemudian dapat Anda jalankan. Ini lebih cocok dengan kerangka kerja di mana Anda dapat mengkompilasi sebagian besar program Anda dengan kompiler normal, tetapi memiliki beberapa ekspresi yang Anda tidak akan tahu sampai run-time, yang ingin Anda jalankan dengan sesuatu yang mendekati kecepatan eksekusi optimal.

Adapun maksud yang jelas dari pertanyaan asli, saya pikir poin dasar dari jawaban asli saya masih berdiri: sementara kompiler JIT dapat beradaptasi dengan hal-hal seperti data yang bervariasi dari satu eksekusi ke yang berikutnya, atau bahkan bervariasi secara dinamis selama satu eksekusi, kenyataannya adalah bahwa ini membuat perbedaan yang relatif kecil setidaknya sebagai aturan umum. Dalam kebanyakan kasus, menjalankan compiler pada saat run time berarti Anda harus melepaskan sedikit optimisasi, jadi yang terbaik yang biasanya Anda harapkan adalah bahwa itu mendekati secepat kompilator konvensional akan menghasilkan.

Meskipun dimungkinkan untuk mendalilkan situasi di mana informasi tersedia untuk kompiler JIT dapat memungkinkannya untuk menghasilkan kode yang jauh lebih baik daripada kompiler konvensional, contoh-contoh ini terjadi dalam praktek tampaknya sangat tidak biasa (dan dalam banyak kasus di mana saya dapat memverifikasi terjadi, itu benar-benar karena masalah dalam kode sumber, bukan dengan model kompilasi statis).

33
Jerry Coffin

Ya, ada kompiler JIT untuk C++. Dari perspektif kinerja murni, saya pikir Profile Guided Optimization (PGO) masih unggul.

Namun, itu tidak berarti bahwa kompilasi JIT belum digunakan dalam praktiknya. Sebagai contoh, Apple menggunakan LLVM sebagai JIT untuk pipeline OpenGL mereka. Itu adalah domain di mana Anda memiliki lebih banyak informasi saat runtime, yang dapat digunakan untuk menghapus banyak kode mati.

Aplikasi lain yang menarik dari JIT adalah Cling, interpreter C++ interaktif berdasarkan LLVM dan Dentang: https://root.cern.ch/cling

Berikut adalah contoh sesi:

[cling]$ #include <iostream>
[cling]$ std::cout << "Hallo, world!" << std::endl;
Hallo, world!
[cling]$ 3 + 5
(int const) 8
[cling]$ int x = 3; x++
(int) 3
(int const) 3
[cling]$ x
(int) 4

Ini bukan proyek mainan tetapi sebenarnya digunakan di CERN, misalnya, untuk mengembangkan kode untuk Large Hadron Collider.

11
Philipp Claßen

C++/CLI dipasangkan. Memang, C++/CLI adalah bukan C++ tetapi cukup dekat. Yang mengatakan Microsoft JIT tidak melakukan optimisasi berbasis perilaku runtime yang super pintar/imut yang Anda tanyakan, setidaknya tidak sepengetahuan saya. Jadi ini benar-benar tidak membantu.

http://nestedvm.ibex.org/ mengubah MIPS menjadi Java bytecode yang kemudian akan dipasangkan. Masalah dengan pendekatan ini dari pertanyaan Anda adalah Anda membuangnya banyak informasi yang berguna pada saat sampai ke JIT.

7
Logan Capaldo

Pertama, saya berasumsi Anda ingin melacak jit daripada metode jit.

Pendekatan terbaik untuk mengambil akan mengkompilasi kode untuk llvm IR, kemudian menambahkan dalam kode tracing, sebelum menghasilkan executable asli. Setelah blok kode menjadi cukup baik digunakan dan sekali informasi yang cukup tentang nilai (bukan jenis seperti dalam bahasa dinamis) dari variabel telah dikumpulkan maka kode dapat dikompilasi ulang (dari IR) dengan penjaga berdasarkan pada nilai-nilai variabel.

Sepertinya saya ingat ada beberapa kemajuan dalam membuat c/c ++ jit di dentang dengan nama libclang.

2
dan_waterworth