Bài viết mới nhất

Tổng 1873 bài
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 8 phút

File C của tôi có 6 lỗi thật mà gcc mặc định im bặt: bật cờ nào bắt được mấy?

Code biên dịch không cảnh báo chưa chắc là code đúng — tôi viết một file C gài sẵn 6 lỗi rồi đo. Mặc định bắt 0/6, -Wall -Wextra bắt 4 nhưng sót rò rỉ và null-deref, chỉ -fanalyzer mới thấy hai lỗi đó. Cú lật cuối: -fanalyzer ở -O2 lại sót chính cái rò rỉ nó bắt ở -O0.