Low Latency Optimization: Using Huge Pages on Linux (Part 2)
Bài tóm tắt Hudson River Trading 2022 3. Quy mô lớn Độ khó: Khó
Phần 2/2. Phần 1: Hudson River Trading 2022.
Hudson River Trading · 2022 · 3. Quy mô lớn · Độ khó: Khó — bài gốc
Bối cảnh
- Bật huge page không chỉ là sửa một file cấu hình. Linux vẫn dùng trang 4 KiB cho phần lớn việc nội bộ; tạo một huge page nghĩa là tìm 512 trang 4 KiB liền nhau bắt đầu ở bội số 2 MiB. Khi bộ nhớ đã phân mảnh, OS phải dồn bộ nhớ, tức là di chuyển trang của chương trình và có thể tạm dừng nó: một nguồn latency spike.
Thay đổi chính
- Transparent Huge Pages (THP), có từ Linux 2.6.38: OS tự thay trang khi thấy được. Chế độ always dễ nhất nhưng chương trình không kiểm soát vùng nào và lúc nào; madvise cho chương trình chọn vùng (sửa code hoặc chèn bằng
LD_PRELOAD). Hợp với chương trình chạy lâu, ngốn bộ nhớ, chịu được spike thỉnh thoảng; OS có thể tách THP khi thiếu bộ nhớ, cũng là spike. Một số phần mềm lớn (MongoDB, Redis, Couchbase) khuyên tắt THP. - hugetlbfs ("explicit huge page"): một pool trang cấp sẵn, cấp phát nhanh như trang 4 KiB nếu pool còn; bộ nhớ trong pool không dùng được cho việc khác nên phải định cỡ cẩn thận; không bị swap. Bẫy: hết pool thì process nhận SIGBUS và chết; mặc định có giữ chỗ lúc
mmap()nhưng vẫn có thể hết khi copy-on-write saufork(). Quy tắc kinh nghiệm: đừng dùng hugetlbfs trong process cần sinh process con. - Hỗ trợ trong allocator: jemalloc, tcmalloc, mimalloc hỗ trợ; JVM, PostgreSQL hỗ trợ hugetlbfs; glibc có tunable
glibc.malloc.hugetlbtừ 2.35. - Chạy code từ huge page (libhugetlbfs, iodlr, tmpfs với option
huge): giảm trượt iTLB nhưng có thể làm hỏng công cụ debug, và mất chia sẻ trang code giữa các instance (tốn bộ nhớ, đẩy L3). - TLB có nhiều tầng và tách lệnh/dữ liệu: ví dụ Cascade Lake có L1 dTLB 32 entry cho trang 2 MiB nhưng 64 entry cho 4 KiB, iTLB chỉ 8 entry cho 2 MiB; L2 dùng chung 1.536 entry. Vì vậy để latency thấp nhất có khi phải giữ vài trang nóng ở 4 KiB.
Vì sao
- Cả THP lẫn hugetlbfs đều có điểm kỳ quặc riêng; theo HRT, chạy benchmark là bắt buộc để chọn cách hợp workload.
Bài học cho SWE
- Tối ưu ở tầng OS đổi một nguồn latency (trượt TLB) lấy nguồn khác (dồn bộ nhớ, tách THP); đo cả phân phối latency chứ không chỉ trung bình.
- Đọc kỹ cách hỏng của từng cơ chế (SIGBUS khi hết pool) trước khi đưa vào production.
- Biết cấu trúc phần cứng cụ thể (số entry TLB theo kích thước trang) trước khi tune.
Liên quan
#huge pages#memory fragmentation#Transparent Huge Pages#THP always/madvise#hugetlbfs#SIGBUS#copy-on-write#fork#jemalloc#tcmalloc#glibc.malloc.hugetlb#code on huge pages#iTLB#dTLB
Được nhắc tới trong
Chủ đề (1)
Công ty (1)
Bài tóm tắt (2)