Dùng & thay cho && trong biểu thức so sánh
Cho mình hỏi về performance khi sử dụng bitwise operator vs arithmetic. Thông thường theo mình hiểu nếu như cần nhân hay chia, thay vì sử dụng * hay /, mình shift bit left hoặc right thì sẽ tối ưu hơn cho performance. Gần như các post mình tìm được trên mạng đều đồng ý với cái đó và cái này thầy mình cũng từng nói. Hôm qua khi ngồi tán dóc với một ông kì cựu trong ngành phát triển game thì ổng nói cái đó không đúng. Mình dẫn chứng bằng tấm hình dưới đây (note từ lớp học) thì ổng nói nó sai.
Mình về google lại thì thấy cái này. https://www.quora.com/Why-are-bitwise-operations-slow-and-CPU-inefficient
Đại khái thì nếu dùng bitwise operator trong trường hợp so sánh Logical, chương trình chạy chậm hơn.
Thấy nó cũng đúng nhưng nếu xét nhân/chia thì bitwise vẫn nhanh hơn. Mình nhớ không lầm thì lúc học Hệ thống, nếu optimize 1 hay 2 gì đó trong C thì compiler sẽ chuyển/nhân chia ra bitwise thay vì vẫn để nhân chia khi không được optimize. Mình có xem hợp ngữ trước và sau optimize thì hợp ngữ viết như vậy.
Kiến thức của mình có bị hổng chổ nào không? Mình có nghe nói về cycle count nhưng không rành lắm. Có trường hợp nào mà arithmetic outperforms bitwise không?

Hi Anh Nguyen.
Chậm hơn thì do nó làm việc thêm việc.
Như nếu ban so sánh
Thì compiler sẽ
Tuy nhiên nếu dùng phép & để so sánh như thế này
Khi đó compiler hiểu là
Dễ thấy việc làm của phép & phải nhiều hơn. Và chưa kể nếu dùng && thì a != b chương trình sẽ ko so sánh tới c và d nữa thế là tiết kiệm cũng kha khá tgian xử lý. Còn ở trường hợp dùng toán tử &, dù a != b thì vẫn tính tiếp c và d. Sau đó lại so sánh lần nữa. Mất công hơn rất nhiều.
Còn về CPU Cycle.
Các lệnh đơn giản như MOV, ADD, OR, XOR, SHL, SHR … chỉ tốn 1 cycle thôi. Nên phép cộng (ở các CPU đời mới) có tốc độ xử lý nhanh bằng một phép dịch trái, dịch phải hoặc phép OR, …
Có các lệnh phức tạp như MUL, IMUL, … thì tốn nhiều hơn nên ưu tiên dùng dịch bit để đẩy nhanh quá trình nhân chia kia các toán hạng ở dạng 2^n.
Cảm ơn các bạn. Mình hỏi là để kiểm tra lại kiến thức của mình thôi chứ mấy cái nhỏ như thế này thì mình để compiler làm. Thêm nữa nếu viết như vậy người khác đọc sẽ khó hiểu hơn so với * hay /.
Bạn có thể dùng godbolt.org mình dùng thì thấy dịch cho x64 ngoài
shl
còn cólea
. Thừa số nhỏ có thể kết hợp vớiadd
, còn lại làimul
3 toán hạng.and
hayor
tính riêng thì nhanh hơn thật vì không có carry nhưng giờ có carry-lookahead rồi nên nhìn tổng thể thì vẫn là 1 cycle.