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

Gộp hai vòng làm một tưởng nhanh hơn — tôi đo, nó chậm đi 2,75 lần

Ghép hai vòng thành một để bớt overhead thì luôn nhanh hơn? Tôi đo và bất ngờ: ghép hai vòng cùng đọc một mảng nhanh 1,8 lần, nhưng ghép hai vòng mỗi vòng ghi một mảng lại chậm 2,75 lần. Thứ quyết định không phải số vòng, mà là số luồng bộ nhớ đan xen trong thân — một bài toán locality.

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

Vòng chép byte tự viết của tôi chậm hơn memcpy 25 lần — thủ phạm là một chữ tôi quên

memcpy là lời gọi thư viện, và vòng chép byte tay nhanh ngang nó? Tôi đo và sai cả hai. memcpy kích thước hằng được inline thẳng thành lệnh vector, 0 lời gọi; còn vòng chép byte tay chậm 25 lần vì compiler sợ hai con trỏ trùng địa chỉ nên không dám tối ưu. Thêm restrict là nó nhanh bằng memcpy ngay.

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

Hai chuỗi "abc" viết ở hai hàm khác nhau lại cùng một địa chỉ — và vì sao đừng mừng vội

Tưởng mỗi literal là một vùng nhớ riêng? Tôi đo: compiler gộp các literal trùng thành một bản duy nhất trong .rodata, nên con trỏ tới chúng bằng nhau và binary nhẹ đi. Nhưng chuẩn C không hề bảo đảm điều đó — dựa vào == để so chuỗi là một bug chờ nổ, luôn dùng strcmp.

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

Đổi chỗ hai dòng for, code chậm đi 16,9 lần — và -O3 chỉ cứu số nguyên, không cứu float

Cùng một phép cộng ma trận, đổi thứ tự hai vòng lồng là chênh 16,9 lần vì cache. Tôi tưởng compiler chịu thua chuyện này. Đo ra -O3 tự đảo thứ tự cứu số nguyên (về 1,0×), nhưng với float thì bó tay — vì đảo thứ tự cộng làm đổi kết quả làm tròn. Ranh giới nằm ở một chỗ rất tinh vi.

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

volatile không làm biến nhanh hơn — nó làm code chậm 5 lần, và tôi vẫn cần nó

Nhiều người tưởng volatile cho nhanh hoặc cho an toàn đa luồng. Tôi đo thì ngược hẳn: volatile chặn tối ưu nên chậm 5,1 lần, vì mỗi lần chạm biến là một chuyến bộ nhớ thật. Nó đúng cho MMIO, cờ ngắt, và biến sink khi đo — nhưng nó KHÔNG phải atomic và không hề an toàn đa luồng.

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

CPU sắp lại thứ tự bộ nhớ thật — 11 lần trong 60 triệu vòng, hiếm tới mức test không bao giờ bắt được

Tưởng CPU luôn chạy theo thứ tự mình viết, còn reorder bộ nhớ chỉ là lý thuyết trong sách? Tôi đo litmus store-buffer trên ARM: reorder xảy ra thật (11 ca trong 60 triệu vòng), rào dmb ish dập được về 0. Nhưng nó hiếm tới ~1 trên 5,5 triệu vòng — nên code sai vẫn qua sạch mọi test rồi nổ ở production.