Vì các câu trả lời khác đều đã được gợi ý đầy đủ, bạn có thể sử dụng __builtin_expect
để cung cấp cho trình biên dịch một gợi ý về cách sắp xếp mã hợp ngữ. Như các tài liệu chính thức đã chỉ ra, trong hầu hết các trường hợp, trình lắp ráp được tích hợp trong bộ não của bạn sẽ không tốt bằng trình lắp ráp do nhóm GCC chế tạo. Tốt nhất bạn nên sử dụng dữ liệu hồ sơ thực tế để tối ưu hóa mã của bạn, thay vì phỏng đoán.
Dọc theo các dòng tương tự, nhưng chưa được đề cập, là một cách cụ thể của GCC để buộc trình biên dịch tạo mã trên một đường dẫn "lạnh". Điều này liên quan đến việc sử dụng các thuộc tính noinline
và cold
, làm chính xác những gì chúng nghe giống như chúng làm. Các thuộc tính này chỉ có thể được áp dụng cho các hàm, nhưng với C ++ 11, bạn có thể khai báo các hàm lambda nội tuyến và hai thuộc tính này cũng có thể được áp dụng cho các hàm lambda.
Mặc dù điều này vẫn thuộc danh mục chung của tối ưu hóa vi mô, và do đó, lời khuyên tiêu chuẩn được áp dụng — hãy thử nghiệm đừng đoán — tôi cảm thấy nó thường hữu ích hơn __builtin_expect
. Hầu như không có bất kỳ thế hệ nào của bộ xử lý x86 sử dụng gợi ý dự đoán nhánh ( tham khảo ), vì vậy điều duy nhất bạn có thể ảnh hưởng đến dù sao là thứ tự của mã lắp ráp. Vì bạn biết mã xử lý lỗi hoặc mã "trường hợp cạnh" là gì, bạn có thể sử dụng chú thích này để đảm bảo rằng trình biên dịch sẽ không bao giờ dự đoán một nhánh với nó và sẽ liên kết nó với mã "nóng" khi tối ưu hóa kích thước.
Sử dụng mẫu:
void FooTheBar(void* pFoo)
{
if (pFoo == nullptr)
{
// Oh no! A null pointer is an error, but maybe this is a public-facing
// function, so we have to be prepared for anything. Yet, we don't want
// the error-handling code to fill up the instruction cache, so we will
// force it out-of-line and onto a "cold" path.
[&]() __attribute__((noinline,cold)) {
HandleError(...);
}();
}
// Do normal stuff
⋮
}
Thậm chí tốt hơn, GCC sẽ tự động bỏ qua điều này để hỗ trợ phản hồi hồ sơ khi nó có sẵn (ví dụ: khi biên dịch với -fprofile-use
).
Xem tài liệu chính thức tại đây: https://gcc.gnu.org/onlineocs/gcc/Common-Function-Attributes.html#Common-Function-Attributes