Giải thuật 03/09/2026 7 phút

Đếm bit 1: vòng lặp 32 nhịp hay một lệnh CPU?

Đếm số bit 1 phải lặp qua từng bit? Đo trên host ARM: đếm bit bằng vòng 32 lần tốn 7,83 ns mỗi số, nhưng lệnh phần cứng __builtin_popcount chỉ 0,25 ns — nhanh 31 lần, và còn nhanh gấp đôi cả mẹo tay Kernighan lẫn bảng tra. Bất ngờ hơn: trình biên dịch không tự nhận ra vòng đếm bit để thay bằng lệnh CNT — phải gọi builtin mới có.

Giải thuật 03/09/2026 7 phút

Bảng tra sẵn: mẹo tối ưu kinh điển đã hết thời?

Tính sẵn kết quả vào bảng tra luôn nhanh hơn tính lại lúc chạy? Đo trên host ARM: một hàm băm 4 phép tính lại chỉ tốn 0,330 ns, còn tra bảng thì tùy kích thước — bảng 4KB trong L1 nhanh 0,284 ns, nhưng bảng 1MB (L2) chậm 1,5 lần và bảng 64MB (RAM) chậm 7,6 lần so với tính lại. Trên CPU hiện đại, chạm bộ nhớ xa đắt hơn tính vài phép rẻ — nên châm ngôn cũ đã lật.

Giải thuật 03/09/2026 8 phút

Thêm phép tính vào vòng lặp mà không chậm hơn: vì sao?

Vòng lặp duyệt mảng lớn nhanh chậm do số phép tính? Đo trên host ARM bằng STREAM: copy (không phép tính), add, triad (nhân+cộng) đều đạt ~65-92 GB/s như nhau — nút cổ chai là băng thông bộ nhớ, không phải phép tính. Và một luồng đã đạt ~85% đỉnh, hai luồng bão hòa ~95 GB/s: trên lõi Apple này một core gần như dùng hết băng thông, khác hẳn server x86.

Giải thuật 03/09/2026 8 phút

Cùng một mảng, chạm cách này nhanh hơn cách kia 424 lần

Truy cập bộ nhớ có một tốc độ cố định? Đo trên host ARM cùng một mảng 256MB, cùng số lần chạm: duyệt tuần tự tốn 0,24 ns mỗi phần tử (33 GB/s), nhưng đuổi con trỏ ngẫu nhiên tốn 101,7 ns — chênh 424 lần. Và ngẫu nhiên độc lập (nhờ song song mức bộ nhớ) chỉ 3,3 ns, nhanh 31 lần đuổi con trỏ. Ba trần khác nhau, chọn bởi cách bạn truy cập.

Giải thuật 03/09/2026 8 phút

Mỗi luồng một biến riêng mà vẫn chậm gấp 2,6 lần?

Mỗi luồng ghi biến riêng của nó thì chạy song song thoải mái? Đo trên host ARM: tám luồng, mỗi luồng tăng một bộ đếm riêng, nhưng nếu tám bộ đếm nằm chung một dòng cache thì chậm gấp 2,6 lần so với khi mỗi bộ đếm được đệm ra dòng riêng — dù các biến hoàn toàn độc lập về logic. Đây là false sharing: dòng cache ping-pong giữa các lõi. Ghi thường không atomic vẫn trả giá.

Giải thuật 03/09/2026 7 phút

Atomic đắt gấp mấy lần? Từ 6,5 tới 74, tùy đông người

Phép atomic có một chi phí cố định, đắt hơn lệnh thường mấy lần? Đo trên host ARM: một luồng, atomic tốn 1,59 ns so với lệnh thường 0,24 ns — gấp 6,5 lần. Nhưng tám luồng cùng đập vào một atomic thì mỗi phép ngốn 18 ns — gấp 74 lần. Còn atomic riêng mỗi luồng (đệm ra dòng cache riêng) chỉ 0,25 ns, scale gần hoàn hảo. Cái đắt là tranh chấp, không phải bản thân atomic.