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

O(log n) mà thua O(n): tìm nhị phân không phải lúc nào cũng thắng

O(log n) < O(n), nên tìm nhị phân luôn thắng tuyến tính? Tôi đo thử: với mảng nhỏ, tuyến tính NHANH HƠN — điểm giao ở khoảng N≈32; dưới đó quét tuần tự thắng nhờ cache và không branch misprediction. Big-O là hành vi tiệm cận (N lớn); N nhỏ thì hằng số và phần cứng mới quyết định.

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

Cùng dữ liệu, đổi cách xếp: nhanh 3,6 lần hoặc chậm 2 lần (SoA vs AoS)

Bố cục struct chỉ là cách tổ chức, không đổi tốc độ? Tôi đo thử: duyệt một trường trên 15 triệu phần tử, SoA nhanh hơn AoS 3,6 lần vì cache line không bị lãng phí. Nhưng truy cập ngẫu nhiên mọi trường thì AoS lại nhanh gấp đôi. Không có bố cục nào luôn thắng — chọn theo mẫu truy cập.

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

Hai biến độc lập vẫn chậm 5 lần: cái bẫy false sharing

Hai luồng, mỗi luồng tăng bộ đếm riêng — độc lập hoàn toàn, phải chạy song song? Tôi đo thử: nếu hai bộ đếm nằm cùng một cache line, chúng chậm hơn 3,8–4,9 lần vì dòng cache ping-pong giữa hai lõi (false sharing). Tách sang cache line riêng (padding) là khắc phục. Không chia sẻ một byte dữ liệu nào vẫn bị phạt vì chung dòng.

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

Đổi một dòng khai báo struct, tiết kiệm 33% RAM: bí mật của padding

Thứ tự khai báo trường trong struct chỉ là chuyện phong cách? Tôi đo thử: đảo thứ tự cùng ba trường làm struct từ 24 byte xuống 16 byte — phí 33% RAM chỉ vì đệm căn lề, và duyệt mảng bản 16B nhanh hơn 1,35 lần vì nhét gấp đôi số struct mỗi cache line. Sắp trường lớn tới nhỏ.