Giả sử tôi có hàm foo() trên một con trỏ lớp cơ sở trừu tượng, mypointer-> foo(). Khi ứng dụng của tôi khởi động, dựa trên nội dung của một tệp, nó chọn khởi tạo một lớp cụ thể cụ thể và gán mypointer cho cá thể đó. Đối với phần còn lại của cuộc đời ứng dụng, con trỏ của tôi sẽ luôn là trỏ đến các đối tượng thuộc loại cụ thể đó. Tôi không có cách nào để biết loại bê tông này là gì (nó có thể được khởi tạo bởi một nhà máy trong thư viện được nạp động). Tôi chỉ biết rằng loại hình này sẽ giữ nguyên sau khi lần đầu tiên một thể hiện của loại bê tông được tạo ra. Con trỏ có thể không phải lúc nào cũng trỏ đến cùng một đối tượng, nhưng đối tượng sẽ luôn luôn có cùng loại bê tông. Lưu ý rằng loại được xác định về mặt kỹ thuật tại 'thời gian chạy' bởi vì nó dựa trên nội dung của một tệp, nhưng sau khi 'khởi động' (tệp được tải) loại được cố định.Bạn có thể nhớ cache tra cứu chức năng ảo trong C++ không?
Tuy nhiên, trong C++ tôi trả chi phí tra cứu chức năng ảo mỗi lần foo được gọi cho toàn bộ thời lượng của ứng dụng. Trình biên dịch không thể tối ưu hóa việc tìm kiếm vì không có cách nào để biết rằng loại bê tông sẽ không thay đổi theo thời gian chạy (ngay cả khi nó là trình biên dịch tuyệt vời nhất, nó không thể suy đoán về hành vi được nạp động thư viện). Trong một ngôn ngữ được biên dịch JIT như Java hoặc .NET, JIT có thể phát hiện rằng cùng một kiểu được sử dụng lặp đi lặp lại và làm inline cacheing. Tôi về cơ bản đang tìm kiếm một cách để tự làm điều đó cho con trỏ cụ thể trong C + +.
Có cách nào trong C++ để lưu bộ nhớ cache tra cứu này không? Tôi nhận ra rằng các giải pháp có thể khá đáng sợ. Tôi sẵn sàng chấp nhận các hacks cụ thể của ABI/trình biên dịch nếu có thể viết các bài kiểm tra cấu hình để khám phá các khía cạnh liên quan của ABI/trình biên dịch để nó "thực tế di động" ngay cả khi không thực sự di động.
Cập nhật: Đối với người trả lời: Nếu điều này không đáng được tối ưu hóa, thì tôi nghi ngờ JIT hiện đại sẽ làm điều đó. Bạn có nghĩ rằng các kỹ sư của Sun và MS đã lãng phí thời gian của họ trong việc triển khai bộ đệm ẩn nội tuyến và không đánh giá nó để đảm bảo có cải thiện không?
sẽ rất thú vị nếu xem LLVM có thể thực hiện thủ thuật JIT về việc này không? – Javier
Có phải cạo thêm một giá trị vô hướng không _all_ sự tấn công này sẽ đòi hỏi phải không? Nghe có vẻ khá hardcore. Tôi có thể nghĩ ra hai cách để làm điều đó: 1. Vá tất cả các cuộc gọi đến hàm ảo với địa chỉ được giải quyết, trong mã đối tượng được nạp. Bạn có thể hack liên kết để làm điều này cho bạn. 2. Sử dụng trampolines. Nhưng tôi không biết nếu đó sẽ có cùng một chi phí như con trỏ chức năng, hoặc thậm chí nhiều hơn. Hãy thử cả hai, và đo lường và xem. :-P –
Tại sao bạn tin rằng chi phí tra cứu chức năng ảo thậm chí còn đáng được tối ưu hóa? Hãy nhớ rằng, "Tối ưu hóa sớm là gốc rễ của tất cả các điều ác". –