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

Đoạn code treo cứng chạy đúng 3089 vòng rồi mới chết: vì sao 'chạy thử thấy chạy' không chứng minh gì

Tưởng khóa nhiều mutex thì thứ tự nào chẳng được, chạy thử thấy chạy là ổn? Tôi tái hiện deadlock thật: hai luồng khóa ngược thứ tự treo cứng — nhưng chạy đúng hàng nghìn vòng, treo ở thời điểm khác nhau mỗi lần. Thuốc là áp một thứ tự khóa toàn cục, hoặc trylock+backoff.

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

Hết deadlock chưa phải hết lỗi: livelock đốt sạch CPU và writer chờ 30ms sau dòng reader

Tưởng không deadlock, không treo là ổn, và trylock tránh deadlock nên an toàn? Tôi đo: livelock chạy hết CPU mà phí 5 lần vì backoff đồng nhịp, và rwlock để dòng reader bỏ đói writer — đọc nhiều hơn ghi 30.000 lần, writer chờ tới 30ms. 'Không treo' không bằng 'mọi luồng đều tiến'.

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

Semaphore không phải 'mutex biết đếm' — và K càng lớn càng nhanh là sai

Tưởng semaphore chỉ là mutex đếm, K càng lớn càng nhanh? Tôi đo: semaphore chặn CỨNG số luồng đồng thời ở đúng K (mutex chỉ là K=1), throughput tăng theo K rồi bão hòa ở K=8; và khác mutex, semaphore không có chủ sở hữu nên báo hiệu được giữa hai luồng khác nhau — thứ mutex không làm được.

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 10 phút

std::async chạy 20.000 việc nhỏ chậm hơn tuần tự 1724 lần — API đẹp không đổi được vật lý

Tưởng future/async tự động nhanh và rẻ? Tôi đo bằng C++: future.get() là một điểm đồng bộ chặn tới khi promise set, và std::async mặc định tạo một luồng mới cho mỗi task — chạy hai vạn task nhỏ bằng async chậm hơn tuần tự 1724 lần. Future tiện cho một kết quả, không phải phép màu song song.

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

Gộp lô đẩy throughput lên 2000 lần — nhưng 'lô càng to càng tốt' là cái bẫy

Tưởng tối ưu đồng bộ là làm mỗi lần đồng bộ nhanh hơn, hoặc batch càng lớn càng tốt? Tôi đo: gộp lô để giảm SỐ LẦN đồng bộ đẩy throughput từ 32 triệu lên 64,6 tỉ ops/giây — 2000 lần; nhưng độ trễ mỗi item cũng tăng ~94 lần theo kích thước lô. Batch tối ưu là cân bằng, không phải cực đại.