Q

Quản trị viên

Là một lập trình viên yêu công nghệ, thích viết blog để chia sẻ kiến thức, kinh nghiệm lập trình và những điều thú vị trong thế giới tech.

2300 bài viết · Website
Linux 01/09/2026 8 phút

Đổi bộ lập lịch I/O — lời khuyên tinh chỉnh phổ biến nhất — cho đúng 0%: chín lần đo ba bộ lập lịch không cái nào tách khỏi nhiễu; nút thật sự cho 10,7 lần thì gần như không ai đụng tới

Ai cũng khuyên đổi bộ lập lịch I/O cho nhanh. Đo thật trên NVMe: none, mq-deadline, kyber cho cùng một dải IOPS và p99, thứ hạng còn đổi giữa các lần chạy — vì bài toán chúng sinh ra để giải đã biến mất cùng đĩa quay. Trong khi đó read_ahead_kb, cái nút gần như không ai chỉnh, tạo chênh lệch 10,7 lần. Bạn đang chỉnh chỗ sáng, không phải chỗ hỏng.

Linux 01/09/2026 9 phút

Trang 2 MB làm chương trình nhanh 1,8 lần — và làm một chương trình chỉ dùng 256 byte chiếm 447 MB; cùng một tính năng, hai mặt đối nghịch tới 219 lần

Dùng trang 2 MB thay 4 KB cắt số lỗi trang và trượt TLB xuống 512 lần — nhưng đo thật cho thấy vùng càng lớn lợi càng nhỏ (ở 1 GB nhân chỉ gom được 47%), và chạm 1 byte trong mỗi vùng 2 MB làm 256 byte dữ liệu ngốn 447 MB. Đây là lý do Redis và MongoDB in cảnh báo khởi động đòi tắt trang lớn trong suốt.

Linux 01/09/2026 9 phút

Đọc 512 byte tốn đúng bằng đọc 16 KB — ba mươi hai lần dữ liệu, cùng một cái giá; còn căn chỉnh sai với O_DIRECT thì không làm chậm, nó khiến lời gọi hỏng thẳng

Hai câu hỏi hay bị gộp làm một — đọc mỗi lần bao nhiêu byte, và có cần căn chỉnh không — hoá ra là hai câu chuyện khác hẳn. Cái giá của một thao tác I/O nằm ở chính thao tác đó (~35 µs cố định), không ở số byte, nên khối dưới 16 KB là tiền vứt đi. Còn O_DIRECT thì căn chỉnh sai không chậm mà trả EINVAL — và ngưỡng là 512 hay 4096 tuỳ phần cứng, một lớp lỗi chỉ lộ khi đổi ổ.

Linux 01/09/2026 9 phút

Cùng một lần đọc RAM tốn 156 ns hoặc 5 ns — chênh 28 lần chỉ tuỳ vào việc CPU có đoán được địa chỉ tiếp theo hay không; tối ưu bộ nhớ đệm không phải đọc ít đi

Con trỏ nối đuôi cho thấy cầu thang L1→RAM chênh 108 lần. Nhưng phép đo thứ hai lật kèo: cùng 256 MB, cùng kiểu trượt cache, các lần đọc độc lập nhanh gấp 28 lần các lần đọc phụ thuộc nhau — vì CPU hiện đại giữ hàng chục yêu cầu bộ nhớ cùng lúc. Nên std::vector<Item> và std::vector<Item*> chứa cùng dữ liệu chênh nhau một bậc độ lớn, và không profiler nào chỉ vào dòng khai báo đó.

Linux 01/09/2026 8 phút

malloc 512 MB xong trong 0,1 mili giây và cấp đúng 0 byte — bộ nhớ thật chỉ xuất hiện khi bạn chạm vào, và lần chạm đầu đắt gấp 90 lần lần sau

mmap 512 MB trả về tức thì với 2 lỗi trang, vì nhân chỉ ghi vào sổ 'vùng này hợp lệ'. Bộ nhớ thật đến từng trang một khi bạn chạm: lỗi trang nhẹ tốn 990 ns so với 11 ns lần sau — 90 lần, và đây là lý do tiến trình vừa khởi động luôn chậm hơn. Cộng thêm hai bất ngờ: nạp sẵn nhanh hơn nạp lười 2,5 lần, và bộ đếm lỗi trang nặng nói dối.

Backend 01/09/2026 7 phút

Memcached đọc nhanh hơn Redis 55% và tốn ít bộ nhớ hơn 61% cho cùng một bộ đệm — nhưng khởi động lại là mất sạch, và đó mới là chỗ quyết định

Đo cả hai trên đúng cùng bài toán khoá–giá trị 100 byte. Không đường ống thì bằng nhau (nút thắt là lượt đi về). Đẩy mạnh thì Memcached thắng vì đa luồng thật, và tốn ít RAM hơn 2,6 lần vì không có lớp đối tượng đa kiểu. Nhưng nó không có lưu trữ, trần 1 MB mỗi giá trị, và không có kiểu dữ liệu nào. Câu hỏi không phải cái nào nhanh, mà là bạn sẽ cần gì trong sáu tháng tới.