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

Tổng 1873 bài
Giải thuật 03/09/2026 8 phút

Benchmark của tôi đo ra 0 nano giây, rồi 4,62 ms, rồi vọt 2,7 lần — bốn cách cái đồng hồ nói dối

Kẹp đồng hồ hai đầu vòng lặp rồi đọc số nghe đơn giản, nhưng con số ấy nói dối bốn kiểu: bỏ sink thì compiler xóa vòng và đo ra 0 ns cho việc chưa chạy; lần đầu chậm 27% vì cache lạnh; trên VM một lần vọt 2,7 lần median; và clock_gettime tốn 16 ns nên đo việc vài ns ra rác. Cách đo cho đáng tin.

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

Lưu x*y vào biến tạm cho nhanh? Compiler đã làm rồi — cái đáng lưu là chỗ khác

Ai cũng được dạy lưu biểu thức chung vào biến tạm cho khỏi tính lại. Tôi đo và thấy compiler tự làm: bản viết lặp và bản lưu tạm sinh mã giống hệt. Nhưng một phép ghi qua con trỏ có thể trùng lại chặn đứng nó, buộc tính lại — và restrict khôi phục, nhanh 1,34 lần ở phép chia. Aliasing mới là thứ quyết định.

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

Thuật toán 'thông minh' của Karatsuba thua nhân tay tới tận 9.800 chữ số

Nhân học sinh O(n²) đáng ra phải thua Karatsuba O(n^1,585) — nhưng đo ra nó thắng tới tận ~1024 hạn (~9.800 chữ số). Ở 64 hạn Karatsuba còn chậm hơn 2,8 lần vì hằng số ẩn của đệ quy. Và mọi phép số lớn chậm hơn nhân 64-bit gốc hàng trăm nghìn lần. Bậc tốt hơn không tự động nhanh hơn. Tôi đo.

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

Vòng lặp 2 tỉ phép tính của tôi đo ra đúng 0 nano giây — vì gcc xóa sạch nó, và đó là bài học nền

Một vòng 2 tỉ phép tính mà kết quả không ai dùng đo ra đúng 0,00 ns — gcc -O2 xóa cả vòng, hàm chỉ còn ret. Thêm một volatile sink là số nhảy lên 1,37 ns thật. Khử mã chết còn xóa dead store và mã sau return, và đây chính là lý do mọi benchmark cần 'quan sát' kết quả.

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

Cái trần O(n log n) mà ai cũng tin là tuyệt đối — hóa ra chỉ là luật một trò chơi

Mọi sắp xếp dựa trên so sánh bị chặn ở O(n log n). Nhưng radix và counting sort chạy O(n): radix thắng introsort 5–11 lần trên số 32-bit ở mọi cỡ, counting sort nhanh 15,6 lần với khóa nhỏ. Giới hạn thật không ở n nhỏ mà ở bề rộng khóa (32-bit 4 lượt, 64-bit 8 lượt) và scatter phá cache. Tôi đo.

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

-O0 chậm hơn -O2 gần 5 lần, còn -O3 gần như không hơn -O2 — cả hai điều tôi tưởng đều sai

Cùng một code C, -O0 chậm 4,6 lần -O2 — không phải vì làm nhiều phép tính hơn, mà vì giữ mọi biến trên ngăn xếp (72 lệnh load/store so với 26 khi lên -O1). Cú nhảy tốc độ lớn nhất nằm ở -O0 → -O1; còn -O2 và -O3 cho mã gần như y hệt. Số cao hơn không đảm bảo nhanh hơn.