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

Một luồng chậm trong tám kéo cả tính toán chậm 1,75 lần: cái bẫy khuếch đại của barrier

Tưởng barrier rẻ, cứ thêm cho chắc? Tôi đo: mỗi rào tốn 8 tới 41 micro giây, tăng theo số luồng vì phải đánh thức cả N luồng; và rào chờ luồng chậm nhất mỗi pha — một luồng nặng gấp 4 trong tám làm cả tính toán 500 pha chậm 1,75 lần. Barrier khuếch đại mọi mất cân bằng tải.

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

"Phải -O3 mới có vector hóa" — niềm tin này đã sai từ gcc 12, và tôi đo để chứng minh

Ai cũng bảo muốn compiler tự vector hóa SIMD thì phải bật -O3. Tôi đo trên gcc 13: -O2 đã sinh 26 lệnh NEON và nhanh gấp 2 lần -O1 scalar, còn -O3 cho mã y hệt. Và cách biết chắc vòng nào được vector hóa không phải đoán theo mức -O, mà là đọc -fopt-info-vec — compiler tự khai.

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

Cùng lượng cache, trải mỏng ra 1024 trang chậm 15 lần

Chỉ cache mới quyết định tốc độ truy cập bộ nhớ? Đo ra: cùng ~128KB dòng cache chạm y hệt nhau, nhưng dữ liệu trải rộng trên 1024 trang chậm gấp 15 lần so với gói gọn trong ~16 trang — 14 ns so với 0,9 ns. Thủ phạm là TLB: bộ nhớ đệm dịch địa chỉ ảo sang vật lý. Trải nhiều trang hơn TLB chứa được thì mỗi truy cập trả thêm một lần đi bảng trang.

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

Hash map O(1) — nhưng có một lần chèn chậm hơn 233.000 lần, và nó không báo trước

Hash map được hứa O(1), nên tưởng mọi lần tra/chèn nhanh như nhau. Đo latency từng lần chèn: trung vị 42 ns, nhưng có một lần 9,8 mili giây khi bảng rehash cả 2 triệu phần tử — chậm hơn 233.000 lần. Tra cũng chậm dần theo load factor, và hàm băm xấu đẩy probe lên 5707. O(1) là trung bình khấu hao. Tôi đo bằng C.