it-swarm-vi.com

Trình biên dịch JIT cho C, C ++ và các lượt thích

Có trình biên dịch đúng lúc nào cho các ngôn ngữ được biên dịch, chẳng hạn như C và C++ không? (Những cái tên đầu tiên xuất hiện trong đầu là Clang và LLVM! Nhưng tôi không nghĩ họ hiện đang hỗ trợ nó.)

Giải trình:

Tôi nghĩ phần mềm có thể được hưởng lợi từ phản hồi cấu hình thời gian chạy và tối ưu hóa mạnh mẽ việc biên dịch lại các điểm nóng khi chạy, ngay cả đối với các ngôn ngữ được biên dịch sang máy như C và C++.

Tối ưu hóa theo hướng dẫn hồ sơ thực hiện một công việc tương tự, nhưng với sự khác biệt, JIT sẽ linh hoạt hơn trong các môi trường khác nhau. Trong PGO, bạn chạy nhị phân của mình trước khi phát hành nó. Sau khi bạn phát hành nó, nó sẽ không sử dụng phản hồi môi trường/đầu vào được thu thập trong thời gian chạy. Vì vậy, nếu mẫu đầu vào được thay đổi, đó là thăm dò hình phạt hiệu suất. Nhưng JIT hoạt động tốt ngay cả trong điều kiện đó.

Tuy nhiên, tôi nghĩ rằng nó còn gây tranh cãi khi hiệu suất biên dịch JIT vượt trội so với chi phí hoạt động của chính nó.

33
Ebrahim Mohammadi

[Xem lịch sử chỉnh sửa cho một câu trả lời hoàn toàn khác về cơ bản đã lỗi thời.]

Có, có một vài trình biên dịch JIT cho C và/hoặc C++.

CLing (như bạn có thể đoán từ trò chơi) dựa trên Clang/LLVM. Nó hoạt động như một thông dịch viên. Đó là, bạn cung cấp cho nó một số mã nguồn, ra lệnh cho nó chạy và nó chạy. Sự nhấn mạnh ở đây chủ yếu là sự tiện lợi và biên dịch nhanh, không tối ưu hóa tối đa. Như vậy, mặc dù về mặt kỹ thuật là một câu trả lời cho chính câu hỏi, điều này thực sự không phù hợp với ý định của OP.

Một khả năng khác là NativeJIT . Điều này phù hợp với câu hỏi hơi khác nhau. Cụ thể, nó không chấp nhận mã nguồn C hoặc C++, và biên dịch nó và thực thi nó. Thay vào đó, nó là một trình biên dịch nhỏ mà bạn có thể biên dịch vào chương trình C++ của mình. Nó chấp nhận một biểu thức về cơ bản được biểu thị dưới dạng EDSL bên trong chương trình C++ của bạn và tạo mã máy thực tế từ đó, sau đó bạn có thể thực thi. Điều này phù hợp hơn nhiều với một khung công tác nơi bạn có thể biên dịch hầu hết chương trình của mình với một trình biên dịch bình thường, nhưng có một vài biểu thức mà bạn sẽ không biết cho đến thời gian chạy, mà bạn muốn thực hiện với thứ gì đó đạt tốc độ thực thi tối ưu.

Đối với mục đích rõ ràng của câu hỏi ban đầu, tôi nghĩ rằng điểm cơ bản của câu trả lời ban đầu của tôi vẫn tồn tại: trong khi trình biên dịch JIT có thể thích ứng với những thứ như dữ liệu thay đổi từ lần thực hiện này sang lần thực hiện tiếp theo hoặc thậm chí thay đổi linh hoạt trong một lần thực hiện, thực tế là điều này tạo ra sự khác biệt tương đối ít nhất là theo quy tắc chung. Trong hầu hết các trường hợp, chạy trình biên dịch trong thời gian chạy có nghĩa là bạn cần phải từ bỏ khá nhiều tối ưu hóa, vì vậy, điều tốt nhất bạn thường hy vọng là nó sẽ nhanh như trình biên dịch thông thường sẽ tạo ra.

Mặc dù có thể đưa ra các tình huống trong đó thông tin có sẵn cho trình biên dịch JIT có thể cho phép nó tạo mã tốt hơn đáng kể so với trình biên dịch thông thường, các trường hợp này xảy ra trong thực tế dường như khá bất thường (và trong hầu hết các trường hợp tôi đã có thể xác minh sự cố xảy ra, đó thực sự là do sự cố trong mã nguồn chứ không phải do mô hình biên dịch tĩnh).

33
Jerry Coffin

Vâng, có trình biên dịch JIT cho C++. Từ góc độ hiệu suất thuần túy, tôi nghĩ Tối ưu hóa hướng dẫn hồ sơ (PGO) vẫn vượt trội.

Tuy nhiên, điều đó không có nghĩa là việc biên dịch JIT chưa được sử dụng trong thực tế. Ví dụ: Apple sử dụng LLVM làm JIT cho đường ống OpenGL của họ. Đó là miền mà bạn có nhiều thông tin hơn trong thời gian chạy, có thể được sử dụng để xóa rất nhiều mã chết.

Một ứng dụng thú vị khác của JIT là Cling, một trình thông dịch C++ tương tác dựa trên LLVM và Clang: https://root.cern.ch/cling

Đây là một phiên mẫu:

[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

Nó không phải là một dự án đồ chơi nhưng nó thực sự được sử dụng trong CERN, ví dụ, để phát triển mã cho Máy Va chạm Hadron Lớn.

11
Philipp Claßen

C++/CLI bị loại bỏ. Cấp, C++/CLI là không C++ nhưng nó khá gần. Điều đó nói rằng JIT của Microsoft không thực hiện các loại tối ưu hóa hành vi thời gian chạy siêu thông minh/dễ thương mà bạn đang hỏi, ít nhất là theo hiểu biết của tôi. Vì vậy, điều này thực sự không giúp đỡ.

http://nestedvm.ibex.org/ biến MIPS thành Java mã byte mà sau đó sẽ bị loại bỏ. Vấn đề với cách tiếp cận này từ câu hỏi của bạn là bạn vứt bỏ rất nhiều thông tin hữu ích tại thời điểm nó được gửi đến JIT.

7
Logan Capaldo

Đầu tiên, tôi giả sử bạn muốn một jit truy tìm hơn là một phương pháp jit.

Cách tiếp cận tốt nhất cần thực hiện là biên dịch mã thành llvm IR, sau đó thêm mã theo dõi, trước khi tạo ra một tệp thực thi riêng. Khi một khối mã được sử dụng đủ tốt và một khi đủ thông tin về giá trị (không phải các loại như trong ngôn ngữ động) của các biến đã được thu thập thì mã có thể được biên dịch lại (từ IR) với các bộ bảo vệ trên các giá trị của các biến.

Tôi dường như nhớ rằng đã có một số tiến bộ trong việc tạo ra một jit c/c ++ trong tiếng kêu dưới tên libclang.

2
dan_waterworth