JIT hiện tại có tối ưu hóa mã máy được tạo để dự đoán nhánh dựa trên thống kê thời gian chạy không?


8

Một số JVM sẽ biên dịch mã byte Java thành mã máy gốc. Chúng tôi biết rằng có rất nhiều tối ưu hóa chúng tôi có thể áp dụng cho điều đó. Gần đây, tôi cũng biết rằng một hoạt động chi nhánh có thể chặn CPU và ảnh hưởng đáng kể đến hiệu suất, nếu CPU đưa ra dự đoán sai.

Có ai biết nếu có bất kỳ JVM nào sẽ tạo mã máy dễ dàng hơn cho CPU để dự đoán đúng dựa trên số liệu thống kê thời gian chạy được thu thập không?


1
Tôi nghĩ HotSpot thực hiện điều này, nhưng CPU cũng có công nghệ dự đoán động kể từ Pentium II, vì vậy nếu nó đưa ra quyết định sai hai lần, nó sẽ tự sửa lần thứ ba nếu nó nhận ra bối cảnh.
Aadaam

Câu trả lời:


6

Không, HotSpot không thêm gợi ý cho bộ dự đoán nhánh phần cứng như đã nêu trong danh sách gửi thư OpenJDK :

Nó đã được xem xét và quyết định chống lại. Các nền tảng mà openjdk hiện đang nhắm mục tiêu đều có dự đoán chi nhánh phần cứng ngoạn mục. Những người không, chẳng hạn như Niagara 1, đã bỏ qua các bit dự đoán. Kết luận là không đáng để làm phức tạp mã với, như David nói, 'macro ma thuật'.


OpenJDK không phải là HotSpot AFAIK.
Florian Margaine

Vâng, đúng vậy. HotSpot là VM là một phần của OpenJDK: openjdk.java.net/groups/hotspot
Rafael Winterhalter

Xấu rồi. Tôi nghĩ HotSpot là VM của Sun và OpenJDK là một sự thay thế nguồn mở.
Florian Margaine

2

Tôi đoán là các gợi ý dự đoán ở cấp độ lệnh máy ít nhất là một tiếng ồn và tệ nhất là sự bất lợi (các byte lệnh lãng phí) đối với kiến ​​trúc thực thi đầu cơ, không theo thứ tự hiện đại. Làm như vậy sẽ giống như bảo CPU ngừng hoạt động - ngừng làm những việc đã thông minh mà nó được thiết kế để thực hiện.


Thứ hai, mức độ dự đoán chi nhánh có thể được cải thiện tùy thuộc vào nguyên nhân dẫn đến sai lầm và mức độ dễ dàng mà người ta có thể đo lường hiệu quả thực hiện hoặc để quan sát xu hướng của chi nhánh.


Tuy nhiên, tôi nghĩ rằng các thủ thuật tối ưu hóa JIT hiện có đã có thể cải thiện dự đoán nhánh ở một mức độ nhất định, ngay cả khi không có sự trợ giúp của các bộ đếm dự đoán sai nhánh CPU.

Chỉ là một ví dụ mã rất đơn giản:

public void repeatHistory(int value)
{
    if (value == 1492)
    {
        landing();
    }
    else if (value == 1776)
    {
        ratifying();
    }
}

Giả sử repeatHistoryđược gọi là rất nhiều lần. Khi trình giám sát hiệu suất dựa trên lấy mẫu phân tích số liệu thống kê ngăn xếp cuộc gọi, có thể thấy rằng, vì bất kỳ lý do gì, repeatHistory()việc gọi ratifying()xảy ra thường xuyên hơn so với cuộc gọi trước landing(). Dựa trên quan sát này, việc truyền mã JIT tiếp theo cho repeatHistoryphương thức sẽ tính đến điều này và thực hiện một hoặc nhiều tối ưu hóa:

  • Di chuyển kiểm tra (value == 1776)trước kiểm tra cho(value == 1492)
  • Cố gắng nội tuyến ratifying()phương thức vào chi nhánh trongrepeatHistory()
  • Nếu repeatHistory()được gọi từ một vòng lặp khác, hãy thử hủy bỏ vòng lặp hoặc đặt repeatHistory()phương thức vào vòng lặp đó.
  • Và nhiều người khác.

Sau khi áp dụng một tối ưu hóa, thường cần phải phân tích lại để xem có thể áp dụng tối ưu hóa nhiều hơn không, bởi vì một tối ưu hóa thường sẽ mở ra nhiều cơ hội hơn.


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.