2012-01-05 26 views
7

Người ta biết rõ rằng Ngôn ngữ Java cho phép người sắp xếp sắp xếp lại các dòng mã được biên dịch miễn là thứ tự lại không có sự khác biệt về ngữ nghĩa mã. Tuy nhiên, trình biên dịch được yêu cầu chỉ bận tâm về sematics như được thấy từ chủ đề hiện tại hiện tại. Nếu đây sắp xếp lại ảnh hưởng đến ngữ nghĩa trong một tình huống đa luồng, nó thường gây ra vấn đề đồng thời (bộ nhớ tầm nhìn)Mô hình bộ nhớ Java: trình biên dịch sắp xếp lại các dòng mã

Câu hỏi của tôi (s):

  1. gì được thực hiện bằng cách cho phép freedm này để trình biên dịch? Là nó thực sự có thể cho trình biên dịch để sản xuất mã đó là hiệu quả hơn bằng cách sắp xếp lại mã? Tôi chưa thấy một trường hợp thực tế cho việc này. Đôi khi tôi cảm thấy rằng những lợi ích nếu có nhiều hơn nhiều so với những rủi ro đồng thời mà điều này có thể đưa ra.

  2. Có cách nào lập trình viên có thể yêu cầu trình biên dịch không sắp xếp lại các dòng như thế này không? Tôi biết rằng bằng cách sử dụng đồng bộ hóa nguyên thủy có hiệu quả xử lý các tác dụng phụ của sắp xếp lại, nhưng tôi hỏi nếu có bất kỳ cách trực tiếp (tùy chọn trình biên dịch) để tắt tính năng này?

Trả lời

8

Trình biên dịch javac có Thực hiện bên cạnh không có optimisations.

Trình biên dịch gốc JIT có thể sắp xếp lại các hướng dẫn khi có sự cố đặt hàng bộ nhớ. Tuy nhiên, CPU cũng có thể sắp xếp lại các lệnh và cập nhật bộ nhớ có cùng tác dụng.

Điều gì đạt được bằng cách cho phép trình gỡ bỏ này đến trình biên dịch?

Lợi ích chính là tính di động của mã. Càng đảm bảo bạn cung cấp, càng khó khăn hơn để đảm bảo mọi nền tảng thực sự thực hiện điều này.

Ngoài ra còn có một cải tiến hiệu suất đáng kể bằng cách cho phép CPU thực hiện các lệnh và khi nó có thể thay vì theo thứ tự nghiêm ngặt.

Trình biên dịch có thể tạo mã hiệu quả hơn bằng cách sắp xếp lại mã không?

Có. nhưng việc sắp xếp lại được thực hiện bởi CPU là quan trọng hơn.

Tôi chưa thấy trường hợp thực tế cho việc này. Đôi khi tôi cảm thấy rằng những lợi ích nếu có nhiều hơn nhiều so với những rủi ro đồng thời mà điều này có thể đưa ra.

Có cách nào lập trình viên có thể yêu cầu trình biên dịch không sắp xếp lại các dòng như thế này không?

Đây là lý do tại sao bạn sử dụng các rào cản bộ nhớ như volatile, synchronized khối và Lock.Khi bạn sử dụng chúng, bạn sẽ nhận được sự đảm bảo an toàn cho luồng.

Tôi biết rằng việc sử dụng đồng bộ hóa nguyên gốc có hiệu quả xử lý các tác dụng phụ của sắp xếp lại, nhưng tôi hỏi xem có cách nào trực tiếp (tùy chọn trình biên dịch) không?

Bạn có thể tắt JIT, nhưng hầu hết việc sắp xếp lại được thực hiện bởi CPU để nó không đạt được nhiều.

Tránh đặt lại các bản cập nhật là một phần nhỏ của vấn đề an toàn chủ đề (vấn đề lớn nhất của nó là tối nghĩa và hiếm khi xảy ra mà làm cho thử nghiệm nó khó) Và một khi bạn viết mã an toàn thread, điều này được giảm bớt.

2

Quá trình sắp xếp lại bytecode được quản lý bởi JIT (Trình biên dịch ngay trong thời gian). Bạn có thể ngừng chạy với các tùy chọn sau đây:

-Djava.compiler=NONE 

Xem thêm ở đây: http://www.cs.swarthmore.edu/~newhall/unixhelp/debuggingtips_Java.html

+1

Thao tác này sẽ không dừng hướng dẫn sắp xếp lại CPU. ;) –

+0

Và nó làm cho chương trình của bạn chạy rất chậm, vì vậy đây không phải là một tùy chọn hữu ích cho bất kỳ việc sử dụng sản xuất nào. – Jesper

2

Có thực sự có thể cho trình biên dịch tạo mã hiệu quả hơn bằng cách sắp xếp lại mã?

Ồ đúng rồi!

Một trong những sự kiện của cuộc sống trong kiến ​​trúc máy tính hiện đại là bộ nhớ là nút cổ chai hiệu suất chính. CPU có thể thực hiện đăng ký để đăng ký các lệnh nhanh hơn nhiều lần so với nó có thể đọc và ghi vào bộ nhớ chính. Đó là lý do tại sao chip hiệu suất cao có 2 hoặc 3 mức bộ nhớ cache. Ngoài ra, các CPU điển hình sử dụng pipelining cho phép nhiều lệnh trong quá trình thực thi cùng một lúc.

Để tận dụng tối đa hiệu suất của CPU với các thuộc tính này, trình biên dịch (và bản thân CPU) cần có khả năng sắp xếp lại các hướng dẫn sử dụng tốt nhất băng thông bộ nhớ và giữ cho đường ống đầy. Mã nguồn gốc cũng cần có khả năng sử dụng các giá trị (của các biến) được lưu trong sổ đăng ký, và giảm thiểu việc sử dụng các hướng dẫn rào cản bộ nhớ đợi cho bộ nhớ ghi để truyền đến bộ nhớ chính. Chúng chỉ được phép (trong Java) vì mô hình bộ nhớ Java cho phép sắp xếp lại.

Lưu ý: chúng tôi đang nói về một tốc độ đáng kể ở đây: có thể tăng tốc 3 đến 5 lần.

Nếu bạn muốn có cảm giác về số lượng, hãy sử dụng ứng dụng chuyên sâu biến dụ và viết lại để tất cả các biến mẫu là volatile. (Điều này sẽ giảm phạm vi sắp xếp lại, và khiến tất cả các lần đọc và ghi đi vào bộ nhớ.) Sau đó, đánh giá hiệu suất của ứng dụng gốc so với phiên bản đã sửa đổi.

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