2013-07-30 37 views
8

Tôi đã tìm thấy một mẹo từ AGGREGATE Magic cho các giá trị tối đa tính toán nhanh. Vấn đề duy nhất mà đây là cho số nguyên, và tuy nhiên tôi đã thử một số điều, không có ý tưởng làm thế nào để làm cho một phiên bản cho số nguyên unsigned.Tối đa chi nhánh nhanh cho các số nguyên không dấu

inline int32_t max(int32_t a, int32_t b) 
{ 
    return a - ((a-b) & (a-b)>>31); 
} 

Bạn có lời khuyên nào?

EDIT

Không sử dụng này, bởi vì như những người khác nói nó tạo ra hành vi không xác định. Đối với bất kỳ kiến ​​trúc hiện đại nào, trình biên dịch sẽ có thể phát ra một lệnh di chuyển có điều kiện không có nhánh từ return (a > b) ? a : b, sẽ nhanh hơn hàm được đề cập.

+24

Chờ đợi, bạn có thực sự chắc chắn điều này nhanh hơn 'return a> b? a: b'? –

+10

Chức năng này khá là vô ích. Sử dụng 'std :: max'. –

+2

Vâng, trên các CPU hiện đại với đường ống, các nhánh đang chậm. Tôi đã đo, phiên bản này nhanh như phiên bản SSE, nếu không nhanh hơn. – plasmacel

Trả lời

9

Mã này làm gì? Nó lấy giá trị của a và sự khác biệt a - b. Tất nhiên, a - (a - b)b. Và (a - b) >> 31 chỉ đơn giản là tạo ra một mặt nạ của những người thân iff a - b là tiêu cực.

Mã này không chính xác, tức là bạn bị tràn trên phép trừ. Tuy nhiên, đó là câu chuyện tương tự như đối với các số nguyên không dấu. Vì vậy, bạn có nội dung với thực tế, mã của bạn không chính xác cho toàn bộ phạm vi giá trị, bạn có thể chỉ cần bỏ qua unsignedness và sử dụng điều này:

inline uint32_t umax(uint32_t a, uint32_t b) { 
    return (uint32_t)max((int32_t)a, (int32_t)b); 
}