2009-08-10 29 views

Trả lời

42

Lưu ý: câu trả lời này là trên ngữ cảnh "mỗi lần chạy".Mã thường được JITted mỗi khi bạn chạy chương trình. Sử dụng ngen hoặc .NET Native cũng thay đổi câu chuyện đó ...

Không giống như HotSpot, CLR JIT luôn biên dịch chính xác một lần mỗi lần chạy. Nó không bao giờ diễn dịch, và nó không bao giờ biên dịch lại với tối ưu hóa nặng hơn trước đây dựa trên việc sử dụng thực tế.

Điều này có thể thay đổi, tất nhiên, nhưng đó là cách đó kể từ v1 và tôi không mong đợi nó thay đổi bất cứ lúc nào sớm.

Ưu điểm là nó làm cho JIT đơn giản hơn rất nhiều - không cần phải xem xét "cũ" mã mà vẫn đang chạy, undo optimisations dựa trên cơ sở đó không còn giá trị, vv

Một điểm. Ưu tiên của NET là hầu hết các ngôn ngữ CLR làm cho các phương thức không ảo theo mặc định, có nghĩa là nhiều nội tuyến hơn có thể được thực hiện. HotSpot có thể inline một phương thức cho đến khi nó được ghi đè lần đầu tại thời điểm đó nó sẽ hủy bỏ việc tối ưu hóa (hoặc thực hiện một số công cụ thông minh trong một số trường hợp có điều kiện vẫn sử dụng mã nội tuyến, dựa trên loại thực tế). Với ít phương pháp ảo hơn để lo lắng, .NET có thể bỏ qua phần lớn nỗi đau vì không thể nội tuyến bất cứ điều gì ảo.

EDIT: Phần trên mô tả khung máy tính để bàn. Compact Framework đưa ra mã gốc khi muốn, JITting lại khi cần thiết. Tuy nhiên, điều này vẫn không giống như tối ưu hóa thích ứng của HotSpots.

Khung vi mô hoàn toàn không JIT, thay vào đó, hãy giải thích mã. Điều này có ý nghĩa đối với các thiết bị rất hạn chế. (Tôi không thể nói tôi biết nhiều về khung vi mô.)

+0

Tôi thấy ... vì vậy thời gian duy nhất mà CLR .Net chạy ở chế độ diễn giải là nếu JIT bị tắt hoàn toàn (để gỡ lỗi). – jsight

+3

Tôi không tin rằng nó thực sự giải thích mã ngay cả sau đó - trình gỡ lỗi có thể bước qua mã được biên dịch một cách thích hợp, đó là tất cả. Mono * có * có một thông dịch viên. –

+1

Thật kỳ lạ, .net MF (MicroFramework cho các thiết bị nhúng) thực hiện IL thay vì biên dịch nó. –

14

Thời gian chạy .NET luôn biên dịch mã JIT trước khi thực thi. Vì vậy, nó không bao giờ được giải thích.

Bạn có thể tìm thấy một số đọc thú vị khác trong CLR Design Choices với Anders Hejlsberg. Đặc biệt là phần:

Tôi đọc rằng Microsoft đã quyết định rằng IL sẽ luôn được biên dịch, không bao giờ được diễn giải. Thông tin loại mã hóa trong hướng dẫn giúp các phiên dịch hoạt động hiệu quả hơn như thế nào?

Anders Hejlsberg: Nếu một thông dịch viên chỉ có thể mù quáng làm những gì các hướng dẫn nói mà không cần phải theo dõi những gì ở trên cùng của ngăn xếp, nó có thể đi nhanh hơn. Khi nó nhìn thấy một iadd, ví dụ, thông dịch viên không phải đầu tiên phải tìm ra loại thêm nó, nó biết đó là một số nguyên thêm. Giả sử ai đó đã xác minh rằng ngăn xếp có vẻ chính xác, an toàn để cắt giảm thời gian ở đó và bạn quan tâm đến điều đó cho một thông dịch viên. Trong trường hợp của chúng tôi, mặc dù, chúng tôi không bao giờ có ý định nhắm mục tiêu một kịch bản diễn giải với CLR. Chúng tôi dự định luôn luôn JIT [Biên dịch ngay trong thời gian], và với mục đích của JIT, chúng tôi cũng cần theo dõi thông tin kiểu. Vì chúng tôi đã có thông tin về loại, nó không thực sự mua cho chúng tôi bất cứ thứ gì để đưa nó vào hướng dẫn.

Venners hóa đơn: Nhiều JVM hiện đại [máy ảo Java] thực hiện tối ưu hóa thích ứng, nơi chúng bắt đầu bằng cách diễn giải bytecode. Họ hồ sơ ứng dụng khi nó chạy để tìm 10% đến 20% mã được thực hiện 80% đến 90% thời gian, sau đó họ biên dịch nó thành nguồn gốc. Tuy nhiên, chúng không nhất thiết phải biên dịch những bytecode. Một bytecode của phương thức vẫn có thể được thực thi bởi trình thông dịch khi chúng được biên dịch thành bản địa và được tối ưu hóa trong nền. Khi mã nguồn gốc sẵn sàng, nó có thể thay thế bytecode. Bằng cách không nhắm mục tiêu một kịch bản diễn giải, bạn đã hoàn toàn loại trừ cách tiếp cận đó để thực thi trong một CLR chưa?

Anders Hejlsberg: Không, chúng tôi chưa hoàn toàn loại trừ điều đó. Chúng ta vẫn có thể giải thích. Chúng tôi không được tối ưu hóa cho việc diễn giải. Chúng tôi không được tối ưu hóa để viết rằng thông dịch viên hiệu suất cao nhất mà sẽ chỉ bao giờ giải thích. Tôi không nghĩ rằng bất cứ ai làm điều đó nữa. Đối với một hộp set top 10 năm trước, điều đó có thể thú vị. Nhưng nó không còn thú vị nữa. Công nghệ JIT đã đạt đến mức bạn có thể có nhiều chiến lược JIT có thể. Bạn thậm chí có thể tưởng tượng bằng cách sử dụng JIT nhanh chóng chỉ trích nhanh, và sau đó khi chúng tôi phát hiện ra rằng chúng tôi đang thực hiện một phương pháp cụ thể mọi lúc, sử dụng một JIT khác dành nhiều thời gian hơn và thực hiện công việc tối ưu hóa tốt hơn. Có rất nhiều điều bạn có thể làm JIT-khôn ngoan.

0

Tôi không tin như vậy và tôi không nghĩ rằng điều đó sẽ xảy ra.

Làm thế nào để JIT biết được bao nhiêu lần một phương pháp cụ thể sẽ được gọi? Sẽ không phải là tần số của yếu tố giải thích vào quyết định?

Tôi cũng đặt câu hỏi về cách trình biên dịch JIT có thể phân tích một hàm để xác định xem việc giải thích có tốt nhất hay không mà không diễn giải chính hàm đó. Và cho rằng thực tế (ít nhất một phương thức đã được thực hiện) sẽ không tốt hơn nếu đơn giản biên dịch từng phương thức để giảm chi phí cố gắng xác định phương thức nào được biên dịch ngay từ đầu?

+0

@Andrew - Số liệu hiệu suất thời gian chạy có thể cho bạn biết liệu điều gì đó có nên được bắt đầu hay không, cũng như mức độ tích cực (b/c một số tối ưu hóa JIT tốn nhiều thời gian hơn những người khác). – jsight

+0

Chỉ là một ý tưởng (tôi nghi ngờ rằng HotSpot hoạt động như thế này) - bạn có thể phân tích một số thứ (như chiều dài của phương thức) tĩnh (trong khi tạo ra bytecode) và đưa ra quyết định hơn, và sau đó, chỉ cần đánh dấu phương thức này với bit "không biên dịch" , vì vậy JIT sẽ biết rằng nó không nên biên dịch nó, khi cần thiết, thay vào đó, trở lại phiên dịch. –

+3

http://java.sun.com/products/hotspot/whitepaper.html - HotSpot có thể thay thế mã tại chỗ, ngay cả khi mã đó đang thực thi trên ngăn xếp. Do đó, một vòng lặp có thể bắt đầu ở chế độ diễn giải, nhưng hoàn thành trong chế độ biên dịch JIT khi biên dịch lại hoàn tất. – jsight

3

Sẽ thật tuyệt khi thấy một số JIT theo dõi trong tương lai đối với các thiết bị có bộ nhớ thấp. Nó sẽ chủ yếu giải thích, tìm các điểm nóng, và chuyển đổi chúng thành lắp ráp và bộ nhớ cache những người. Tôi nghĩ rằng đây là những gì Google làm với JIT Android của họ và Microsoft Research có một dự án nghiên cứu đang diễn ra cho JIT dựa trên dấu vết.

Tôi tìm thấy một bài viết, SPUR: A Trace-Based JIT Compiler for CIL .. Có thể một số điều này sẽ biến nó thành CLR một ngày?

Các vấn đề liên quan