Nếu bạn đã lược tả mã của mình một cách cẩn thận và thấy rằng toán tử modulo là chi phí chính trong vòng lặp bên trong thì có một tối ưu hóa có thể hữu ích. Bạn có thể đã quen thuộc với các trick để xác định dấu hiệu của một số nguyên sử dụng số học trái ca (cho các giá trị 32 bit):
sign = (x >> 31) | 1;
này mở rộng bit dấu trên chữ, vì vậy giá trị tiêu cực mang lại -1 và tích cực giá trị 0. Sau đó bit 0 được thiết lập sao cho giá trị dương đạt được trong 1.
Nếu chúng tôi chỉ tăng giá trị bằng số lượng nhỏ hơn modulo thì có thể sử dụng cùng một kết quả này để kết quả:
val += inc;
val -= modulo & (static_cast<int32_t>(((modulo - 1) - val)) >> 31);
Hoặc, nếu bạn đang giảm dần theo giá trị nhỏ hơn modulo thì mã có liên quan là:
int32_t signedVal = static_cast<int32_t>(val - dec);
val = signedVal + (modulo & (signedVal >> 31));
Tôi đã thêm toán tử static_cast vì tôi đã chuyển sang uint32_t, nhưng bạn có thể không thấy chúng cần thiết.
Điều này có giúp ích nhiều như trái ngược với toán tử% đơn giản không? Điều đó phụ thuộc vào trình biên dịch và kiến trúc CPU của bạn. Tôi tìm thấy một vòng lặp đơn giản chạy nhanh hơn 60% trên bộ vi xử lý i3 của tôi khi biên dịch theo VS2012, tuy nhiên trên chip ARM11 trong Raspberry Pi và biên dịch với GCC tôi chỉ có một cải tiến 20%.
Nguồn
2013-05-08 09:37:52
"là mã này liên quan đến các vòng lặp đủ hiệu quả, so với% toán tử?" Bạn cho chúng tôi biết, bạn là người sử dụng chương trình. Nó có cảm thấy chậm không? Bạn thậm chí có thể nhận thấy? Bạn đã lược tả và thấy điều này có chậm không? – GManNickG
Điều đó sẽ phụ thuộc vào kích thước. Nếu 'b = 1000000000' và' c = 3'. Sẽ mất một lúc ... – Mysticial
Bạn có thể nói cho CPU mục tiêu và trình biên dịch không? Nếu không có điều đó thì không thể so sánh bất kỳ cách tiếp cận nào. – fghj