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

Bật -funroll-loops phình mã gấp 2,6 lần mà không nhanh hơn một giây — lợi thật của bung vòng nằm ở chỗ khác

Bung vòng để 'giảm nhánh' là lời giải thích bỏ lỡ điều quan trọng. Tôi đo: bung với nhiều biến tích lũy độc lập nhanh 3,72 lần vì phá chuỗi phụ thuộc, nhưng bung cơ học của -funroll-loops phình mã 121→314 lệnh mà 0 tăng tốc — và bung x8 còn chậm hơn x4. Cái đáng làm không phải chép thân vòng.

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

Vì sao bung vòng x8 lại chậm hơn x4? Tôi đếm lệnh và tìm ra thủ phạm: CPU hết thanh ghi

CPU chỉ có ~28 thanh ghi số nguyên dùng được trên AArch64; vượt ngưỡng đó, biến sống cùng lúc bị tràn ra ngăn xếp, và lệnh load/store trong vòng nóng leo từ 1 (4 biến) lên 103 (48 biến). Đây chính là lời giải cho bí ẩn bung vòng x8 chậm hơn x4 — và vì sao biến cục bộ không hề miễn phí.

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

Cùng một hàm, cùng đầu vào, hai kết quả: 1 với -O2 và 1073741824 với một cờ — dấu vân tay của UB

Đọc lại bit của một int như float bằng ép kiểu con trỏ nghe vô hại. Tôi đo: cùng hàm trả về 1 với -O2 nhưng 1073741824 với -fno-strict-aliasing — một cờ đổi kết quả là bằng chứng chắc chắn của hành vi không xác định. Strict aliasing cho tốc độ ~9%, nhưng type-punning ép kiểu vi phạm nó; memcpy mới đúng, mà vẫn nhanh.

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

Bật -ffast-math: tổng 20 triệu số chạy nhanh gấp 4 — nhưng ra một con số khác

-ffast-math nghe như nút tăng tốc miễn phí cho code toán. Tôi đo: cùng tổng 20 triệu float, -O3 cho 1999531776 trong 0,571 ns/phần tử, còn -ffast-math cho 1999546496 trong 0,143 ns — nhanh 4 lần nhưng KHÁC kết quả, vì nó sắp lại phép cộng để vector hóa mà số thực máy không kết hợp. Tốc độ đổi lấy độ chính xác.

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

Hàm kiểm tràn tôi viết bị gcc rút thành 'luôn trả về 0' — vì tôi vô tình hứa với nó rằng tràn không xảy ra

Hành vi không xác định (UB) chỉ là 'crash hoặc giá trị rác'? Tôi đo và thấy nó là một lời hứa compiler tin tuyệt đối, rồi xóa chính những kiểm tra an toàn tôi viết: if(p==NULL) sau khi deref, if(a+100<a) kiểm tràn — cả hai biến mất ở -O2, để lỗi lọt qua im lặng. Cái tối ưu UB mở khóa nằm ở mã, không phải ở đồng hồ.

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

Tưởng -O2 đã vắt kiệt, thêm mỗi cờ -flto mà nhanh 1,59 lần — vì nó nhìn thấy thứ -O2 không thấy

-O2 tưởng là trần tối ưu cho production? Tôi đo và thấy nó chỉ tối ưu trong PHẠM VI MỘT FILE — ranh giới file chặn nội tuyến xuyên hàm. Bật -flto phá ranh giới đó: hàm hot ở file khác được nội tuyến, lệnh gọi biến mất khỏi vòng nóng, nhanh 1,59 lần chỉ nhờ thêm một cờ.