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

Bật hết -O3 -Ofast -march=native cho chắc? Đo ra chỉ một cờ nhanh thật — và nó đổi kết quả

Tưởng cứ -O3 -Ofast -march=native -funroll là nhanh nhất? Tôi đo một workload thật: -O3 bằng -O2, -march không đổi, -funroll chỉ 3%, chỉ -ffast-math nhanh 2,9 lần nhưng đổi kết quả số thực. Không có combo cờ thần — mỗi cờ là một đánh đổi phụ thuộc workload, và cách duy nhất chọn đúng là đo ở đúng máy, đúng cờ, đúng code của bạn.

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

push_front vào vector: quả bom O(n) núp trên đường nóng

Cần thêm phần tử ở đầu danh sách? Nhiều người bảo dùng vector cũng được. Tôi đo thử — và vector push_front hóa ra là O(n): mỗi lần thêm gấp đôi thời gian khi số phần tử gấp đôi (1552 → 3375 ns), vì nó phải dịch cả mảng. Một ring buffer chỉ lùi một chỉ số, O(1) (~3 ns), nhanh hơn 1136 lần ở N=100k. Còn std::deque thì push được hai đầu O(1), duyệt chỉ chậm hơn vector 19%.

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

Cùng một hàm constexpr: một chỗ chạy 0,227 ns, chỗ kia 45625 ns — khác nhau ở đâu?

Đánh dấu constexpr là chắc chắn tính sẵn lúc biên dịch, 0 chi phí? Tôi đo và phát hiện chữ đó hứa ít hơn tưởng. Đặt kết quả vào biến constexpr thì nó thành literal đọc 0,227 ns; gọi đúng hàm ấy với đầu vào động thì nó chạy nguyên vòng lặp lúc chạy, 45625 ns. Ngữ cảnh mới quyết định, không phải từ khóa.

Hệ điều hành 03/09/2026 8 phút

Tôi bỏ file khỏi cache rồi đọc lại — vẫn nhanh như thường: khi môi trường đo giấu mất chính thứ tôi định đo

Page cache giữ file trong RAM để đọc lại tức thì (Cached 5,5GB, đọc 256MB ở ~36GB/s, 0 lỗi trang nặng). Nhưng trong container tôi không tạo nổi lần đọc 'nguội': overlayfs không có đĩa chậm thật bên dưới, FUSE thì bỏ qua page cache khách nên luôn chậm. Đo I/O trong container là đo tầng ảo hóa, không phải đĩa.

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

unordered_map dùng chaining — nhưng đó có phải cách nhanh nhất?

std::unordered_map dùng chaining nên chaining là cách nhanh nhất xử lý va chạm? Đo ra: open addressing (dò trong một mảng liền) tra cứu nhanh hơn ở hệ số tải vừa (10,4 vs 15,1 ns ở tải 0,5) và gọn hơn 3,4 lần bộ nhớ. Nhưng ở tải 0,9, dò dồn cụm trung bình 5,45 lần khiến open chậm hẳn và chaining vượt lên — một điểm giao rõ ràng.

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

fork chỉ tốn 74µs dù cha giữ gì — nhưng cấp 256MB trước rồi fork lại chậm 1,86 lần

Tưởng fork đắt vì phải sao chép cả bộ nhớ? Tôi đo: Copy-on-Write nên fork KHÔNG chép dữ liệu — chỉ 74µs, 1,6 lần một luồng. Nhưng CoW không làm fork miễn phí theo kích thước: fork sau khi cấp 256MB chậm 1,86 lần vì vẫn phải nhân đôi bảng trang. CoW cắt chép dữ liệu, không cắt chép bảng trang.