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

Ép always_inline cho hàm nóng để chắc nhanh? Tôi đo: nó thừa — kẻ thật sự đổi cuộc chơi là noinline

Ai cũng khuyên ép always_inline cho hàm nóng, và sợ nội tuyến hàm to làm phình mã chậm. Tôi đo và cả hai đều lệch: always_inline hàm nhỏ là thừa (compiler đã inline), hàm to vẫn nhanh 2 lần dù mã phình 3,2 lần. Kẻ có tác động thật là noinline — cấm inline làm chậm 2,3 lần vì chặn cả vector hóa.

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

Đổi thứ tự 6 trường trong struct: 40 byte xuống 24, và mảng duyệt nhanh 1,6 lần

Sắp trường struct thế nào cũng vậy, compiler lo? Tôi đo và thấy chính thứ tự bạn khai quyết định kích thước: cùng 6 trường, thứ tự xấu phình 40 byte vì padding, thứ tự tốt chỉ 24 — và mảng 20 triệu phần tử duyệt nhanh 1,6 lần chỉ vì gọn hơn. Compiler bị cấm tự đổi thứ tự, nên đây là tối ưu miễn phí chỉ bạn làm được.

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

Tôi malloc một struct rồi free — gcc xóa sạch cả hai, làm như tôi chưa từng viết

Khai struct local là chắc chắn tốn ô nhớ stack, malloc thì tốn heap? Tôi đo và thấy compiler làm biến mất cả hai khi chứng minh được đối tượng không thoát khỏi hàm: struct thành thanh ghi, malloc/free bốc hơi, tốc độ y hệt. Cái đắt không phải việc khai hay cấp phát — mà là lấy địa chỉ (&) khiến nó thoát ra ngoài.

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

Hàm ảo "luôn chậm nên tránh"? Tôi đo: cùng lời gọi đó chênh nhau 6,6 lần tùy dữ liệu

Ai cũng bảo tránh virtual cho nhanh. Tôi đo và thấy nó phụ thuộc một thứ lời khuyên đó bỏ qua: khi một điểm gọi chỉ thấy một kiểu (monomorphic) thì gọi ảo gần bằng gọi trực tiếp — 0,722 ns; chỉ khi nhiều kiểu trộn khó đoán (megamorphic) mới chậm 6,6 lần. Cái đắt là đích nhảy khó đoán, không phải từ khóa virtual.

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

-march=native nhanh 2,66 lần — rồi làm vỡ build ngay trước mắt tôi

Cứ bật -march=native cho nhanh? Tôi đo và thấy hai mặt: -march đúng mở khóa lệnh dotprod cho kernel int8 nhanh 2,66 lần thật, nhưng -march=native trong container này còn không build nổi vì assembler từ chối lệnh gcc phát ra. Rủi ro mong manh của nó hiện ngay lúc build, chưa nói tới SIGILL lúc chạy trên máy khác.

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

Chia cho 7 gần như miễn phí, chia cho một biến đắt gấp 2,7 lần — cùng một dấu gạch chéo

Chia là chia, tốn như nhau? Tôi đo và thấy cùng dấu / cho hai chi phí khác hẳn: chia cho hằng số biến thành nhân magic + dịch (vector hóa được, gần như miễn phí), còn chia cho biến là udiv đắt 2,7 lần. Nhưng trong chuỗi phụ thuộc, cái mẹo magic lại không thắng — lợi ở thông lượng, không ở độ trễ.