Làm thế nào nhiều việc sử dụng các macro có khả năng và các macro macro không có khả năng là quá nhiều?


12

Các macro thường được gọi là likelyunlikelymacro giúp trình biên dịch biết liệu ifthường sẽ được nhập hoặc bỏ qua. Sử dụng nó dẫn đến một số cải tiến hiệu suất (khá nhỏ).

Tôi đã bắt đầu sử dụng chúng gần đây và tôi không chắc nên sử dụng những gợi ý như vậy thường xuyên như thế nào. Tôi hiện đang sử dụng nó với ifs kiểm tra lỗi , thường được đánh dấu là unlikely. Ví dụ:

mem = malloc(size);
if (unlikely(mem == NULL))
  goto exit_no_mem;

Có vẻ ổn, nhưng việc kiểm tra lỗi ifxảy ra khá thường xuyên và do đó việc sử dụng các macro đã nói.

Câu hỏi của tôi là, có quá nhiều để có likelyunlikelymacro trên mỗi kiểm tra lỗi ifkhông?

Trong khi chúng ta đang ở đó, những nơi khác họ thường sử dụng?


Theo cách sử dụng hiện tại của tôi, nó nằm trong một thư viện tạo ra sự trừu tượng hóa từ hệ thống con thời gian thực, vì vậy các chương trình sẽ trở nên di động giữa RTAI, QNX và các hệ thống khác. Điều đó nói rằng, hầu hết các chức năng là khá nhỏ và gọi trực tiếp một hoặc hai chức năng khác. Nhiều static inlinechức năng thậm chí .

Vì vậy, trước hết, nó không phải là một ứng dụng tôi có thể cấu hình. Không có nghĩa gì khi "xác định cổ chai" vì đây là thư viện, không phải là ứng dụng độc lập.

Thứ hai, nó giống như "Tôi biết điều này là không thể, tôi cũng có thể nói với trình biên dịch". Tôi không tích cực cố gắng để tối ưu hóa if.


7
những người siêu vi tối ưu hóa với tôi ...
ratchet freak

2
Đối với mã ứng dụng, tôi chỉ thêm chúng nếu hồ sơ cho thấy mã này được sử dụng trong đường dẫn nóng.
CodeInChaos


@james, điều đó chỉ nói likelyunlikelytồn tại và những gì họ làm. Tôi đã không tìm thấy bất cứ điều gì thực sự sẽ đề xuất khi nào và nơi nào là tốt nhất để sử dụng chúng.
Shahbaz

@Shahbaz "Nếu điều kiện thường xuyên sai, việc thực thi không tuyến tính. Có một đoạn lớn mã không được sử dụng ở giữa, điều này không chỉ gây ô nhiễm L1i do tìm nạp trước, nó còn có thể gây ra vấn đề với dự đoán nhánh. Nếu dự đoán nhánh sai, biểu thức điều kiện có thể rất kém hiệu quả. " Vì vậy, các vòng lặp chặt chẽ nơi bạn muốn đảm bảo các hướng dẫn bạn cần có trong bộ đệm L1i
James

Câu trả lời:


12

Bạn có cần hiệu năng tệ đến mức bạn sẵn sàng làm ô nhiễm mã của mình với điều đó không? Đó là một tối ưu hóa nhỏ.

  • Liệu mã chạy trong một vòng lặp chặt chẽ?
  • Ứng dụng của bạn có vấn đề về hiệu suất?
  • Bạn đã định hình ứng dụng của mình và xác định rằng vòng lặp đặc biệt này tốn rất nhiều thời gian của CPU chưa?

Trừ khi bạn có thể trả lời yestất cả những điều trên, đừng bận tâm với những thứ như thế này.

Chỉnh sửa: để đáp ứng với chỉnh sửa. Ngay cả khi bạn không thể lập hồ sơ, bạn thường có thể ước tính các điểm nóng. Hàm phân bổ bộ nhớ được mọi người gọi là một ứng cử viên tốt, đặc biệt vì nó chỉ yêu cầu sử dụng một macro duy nhất để làm việc cho toàn bộ thư viện.


1
Để rõ ràng, tôi đã không bỏ phiếu cho bạn. Tuy nhiên, câu trả lời của bạn không thực sự trả lời câu hỏi của tôi. Bạn đang cố gắng nói rằng (un)likelymacro hiếm khi được sử dụng và chỉ trong mã quan trọng cực kỳ hiệu năng? Là "thực hành xấu" để sử dụng nó thường xuyên, hoặc chỉ "không cần thiết"?
Shahbaz

@Shahbaz Nó làm cho mã ít đọc hơn và tối ưu hóa hiệu suất có thể dao động từ mức tăng tầm thường đến mất tầm thường. Cái sau khi giả định về khả năng là không chính xác hoặc đã thay đổi thành không chính xác do sự thay đổi sau này sang các phần khác của mã. Nếu không bao giờ nên được sử dụng trừ khi cần thiết.
Peter

3
@ Peter: Trong khi nó quá xấu cú pháp không phải là đẹp hơn, ký hiệu như những gì có thể hoặc không thể cung cấp thông tin hữu ích cho con người đang đọc mã. Ví dụ, một người đã nhìn thấy if (likely(x==2 || x==3)) doOneThing(); else switch(x) { ... }, có thể đánh giá rằng việc lập trình viên sử dụng ifgiá trị 2 và 3 không chỉ đơn thuần là hậu quả của việc lập trình viên không biết rằng C có thể liên kết hai casenhãn với một trình xử lý.
supercat

Không ai đã đề cập đến những gì tôi cảm thấy là một điểm quan trọng. Không chỉ là con đường "không thể xảy ra" xảy ra ít thường xuyên hơn, có thể là do điều kiện trên con đường đó xảy ra mà bạn không quan tâm đến tốc độ. Chẳng hạn, một thiết bị ngoại vi trở nên không phản hồi nên bạn phải đặt lại và ngủ.
Benjamin Lindqvist

2

Nếu bạn đang viết cho x86 / x64 (và không sử dụng CPU 20 năm tuổi), hiệu suất đạt được từ việc sử dụng __builtin_recect () sẽ không đáng kể nếu có. Lý do cho điều đó là các CPU x86 / x64 hiện đại (không chắc chắn 100% về Atom), có dự đoán nhánh động, do đó, về cơ bản CPU "học" về nhánh được lấy thường xuyên hơn. Chắc chắn, thông tin này chỉ có thể được lưu trữ cho một số chi nhánh hạn chế, tuy nhiên, chỉ có hai trường hợp có thể. Nếu (a) nó là một nhánh "được sử dụng thường xuyên", thì chương trình của bạn sẽ được hưởng lợi từ dự đoán nhánh động đó và nếu (b) đó là nhánh "hiếm", bạn sẽ không thực sự thấy bất kỳ hiệu suất thực tế nào do dự đoán sai trong các nhánh hiếm như vậy (20 chu kỳ CPU của sự hiểu sai nhánh không quá tệ nếu nó xảy ra một lần trong một mặt trăng xanh).

Lưu ý: điều này KHÔNG ngụ ý rằng tầm quan trọng của x86 / x64 hiện đại của việc hiểu sai chi nhánh đã giảm xuống: bất kỳ chi nhánh nào có 50-50 cơ hội nhảy không bị phạt sẽ vẫn bị phạt (các chu kỳ CPU IIRC 10-20), do đó, trong các vòng lặp bên trong các nhánh có thể vẫn cần phải tránh Điều quan trọng duy nhất của __builtin_Exect () trên x86 / x64 đã giảm đi (IIRC, khoảng 10-15 năm trước hoặc lâu hơn) - chủ yếu là do dự đoán nhánh động.

NB2: cho các nền tảng khác ngoài x86 / x64, YMMV.


Vâng, trình biên dịch biết nhánh nào mà CPU sẽ mong đợi ít có khả năng hơn. Và nó có thể sắp xếp cho điều đó thực sự không thể xảy ra. Nhưng trình biên dịch có thể đã biết mẫu đó mà không có chú unlikelythích.
Ded

@Ded repeatator: với dự đoán nhánh động, trình biên dịch không biết nhánh nào có khả năng hơn vì CPU tính toán nó trong thời gian chạy dựa trên các lần chạy trước thông qua chính điểm này trong mã.
No-Bugs Hare
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.