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

45 phép đo về code đồng thời, và một sự thật: trực giác của bạn gần như luôn sai

Bài kết của sê-ri 45 phần đo thật về đồng thời. Ba tầng bài học và những con số đáng nhớ — tạo luồng 47µs, 10 lõi chỉ 4,65 lần, atomic tranh chấp chậm 27 lần, false sharing 4 lần — cùng một điều xuyên suốt: với đồng thời, đoán thì sai, chỉ đồng hồ mới nói thật.

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

Một system call tốn 103ns — 450 lần một phép tính; nhưng clock_gettime chỉ 12,7ns vì không vào nhân

Tưởng getpid() được glibc cache nên gần như free, và hàm nào trông như syscall cũng vào kernel? Tôi đo: một syscall thật ~103ns (450× một phép tính), getpid glibc không còn cache nên vẫn 100ns, còn clock_gettime qua vDSO chỉ 12,7ns vì chạy hẳn trong user mode. 'Trông như syscall' không quyết định giá.

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.

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

fork rẻ nhờ Copy-on-Write, nhưng lần GHI đầu vào mỗi trang tốn 909ns — 96 lần ghi sau

Tưởng sau fork con đọc/ghi đều như thường, và Copy-on-Write gần như miễn phí? Tôi đo: đọc trang rẻ (15,6ns) nhưng lần ghi đầu vào mỗi trang tốn 909ns — 96 lần lần ghi sau — vì mỗi trang phải chịu một CoW fault (bẫy, cấp trang, chép 4KB). CoW không free, chỉ hoãn cái giá chép.

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

Binary động nhỏ hơn 12 lần nhưng khởi động CHẬM hơn — vì exec không chỉ 'nhảy vào'

Tưởng exec chỉ là nhảy vào chương trình mới nên tức thì? Tôi đo: execve tốn 45,6µs cho binary tĩnh (nạp ELF, ánh xạ segment), và 73,5µs cho binary động — chậm 1,61 lần dù file nhỏ hơn 12 lần, vì trình liên kết ld.so phải phân giải symbol trước main. Nhỏ trên đĩa không bằng nhanh lúc chạy.

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

Chuyển ngữ cảnh giữa hai tiến trình chỉ đắt hơn hai luồng 1,09 lần — sách cũ nói sai chỗ nào

Tưởng chuyển ngữ cảnh giữa hai tiến trình đắt hơn nhiều so với giữa hai luồng vì phải flush TLB? Tôi đo: chỉ 1,09 lần (579ns vs 532ns) — CPU hiện đại gắn ASID/PCID nên đổi bảng trang không cần flush. Nhưng đó chỉ là chi phí trực tiếp; khác biệt thật ngoài đời là gián tiếp (cache nguội).