1 điểm bởi GN⁺ 2024-08-27 | 1 bình luận | Chia sẻ qua WhatsApp

vmsplice quá nhanh

  • Một số chương trình sử dụng lời gọi hệ thống vmsplice để chuyển dữ liệu qua pipe nhanh hơn
  • Khi không dùng vmsplice, người ta phát hiện pipe trên Linux chậm hơn dự kiến
  • Tác giả đang viết một chương trình mã hóa/giải mã mã Morse tốc độ cao và đang dùng pipe cho việc này

Ghi dữ liệu trong môi trường lý tưởng

  • Chương trình bên dưới sao chép dữ liệu mà không cần lời gọi hệ thống
  • Sử dụng AVX-512 và chạy ở tốc độ 167 GB/s
  • Khi tắt AVX-512 và thử với AVX2 cùng SSE2, vẫn ghi nhận cùng tốc độ 167 GB/s
  • Miễn là có vector hóa, có thể đạt tốc độ 167 GB/s

Thực sự ghi dữ liệu vào pipe

  • Sau khi viết chương trình ghi dữ liệu vào pipe và đo đạc, tác giả ghi nhận tốc độ 17 GB/s
  • Con số này chậm hơn 10 lần so với ghi vào bộ đệm
  • Kết quả profiling cho thấy phần lớn thời gian bị tiêu tốn trong lệnh gọi write
  • Hàm pipe_write mất nhiều thời gian để cấp phát các trang bộ nhớ
  • Bản thân việc sao chép dữ liệu chỉ chiếm 20% thời gian CPU, nhưng vẫn chậm gấp đôi __memset_avx512_unaligned_erms

Nhờ đến vmsplice

  • vmsplice di chuyển bộ đệm từ không gian người dùng sang kernel mà không sao chép dữ liệu
  • Dùng vmsplice có thể đạt tốc độ 210 GB/s
  • vmsplice bỏ qua phần tốn kém trong lệnh gọi hệ thống write

Kết luận

  • Ghi vào pipe chậm hơn 10 lần so với ghi vào bộ nhớ thô
  • Nguyên nhân là chi phí khóa bộ đệm và chi phí lưu/khôi phục ngữ cảnh SIMD
  • splicevmsplice tránh được các chi phí này và di chuyển dữ liệu hiệu quả

Tóm tắt của GN⁺

  • Bài viết giải thích cách tối đa hóa hiệu năng pipe trên Linux bằng vmsplice
  • vmsplice cải thiện hiệu năng đáng kể bằng cách di chuyển dữ liệu trực tiếp mà không sao chép vào không gian kernel
  • Hữu ích cho các chương trình xử lý dữ liệu tốc độ cao như mã hóa/giải mã mã Morse
  • Các dự án khác có chức năng tương tự gồm splicesendfile

1 bình luận

 
GN⁺ 2024-08-27
Ý kiến trên Hacker News
  • Lý do JMP không được thay bằng RET là do tùy chọn CONFIG_RETHUNK

    • Có thể thấy trong phần disassembly của objdump rằng RET đã được thay bằng JMP __x86_return_thunk
    • Liên kết liên quan: Liên kết1, Liên kết2
  • Các lệnh NOP ở đầu và cuối hàm cho phép ftrace chèn lệnh theo dõi

    • Xuất phát từ các macro ASM_CLAC và ASM_STAC
    • Nếu phát hiện X86_FEATURE_SMAP, chúng sẽ được điền bằng các lệnh CLAC và STAC lúc runtime
    • Liên kết liên quan: Liên kết3, Liên kết4, Liên kết5
  • Side project của một người dùng đề xuất một system call cung cấp ring buffer cho file descriptor

    • Nếu cả hai đầu của pipe đều hỗ trợ ring buffer, có thể map cùng một ring buffer để thực hiện zero-copy IO mà không cần gọi kernel
    • Người này đang tìm cộng tác viên
    • Liên kết liên quan: Liên kết6
  • Gọi Linux pipe là "chậm" cũng giống như gọi Toyota Corolla là "chậm"

    • Trong hầu hết trường hợp, nó đã đủ nhanh
    • Trừ những trường hợp cực đoan, không cần tìm thứ gì nhanh hơn
  • Trên CPU hiện đại, rep movsb nhanh ngang với phiên bản vector hóa nhanh nhất

    • Tên hàm kernel "copy_user_enhanced_fast_string" cho thấy điều đó
    • Các tính năng CPU ERMS và FSRM giúp điều này khả thi
  • AVX512 tiêu thụ nhiều điện năng và gây ra việc scale tần số CPU

  • Đang lại trải nghiệm "hug of death" từ Hacker News

    • Nhờ các trang WordPress được cache mà tình hình khá hơn, nhưng vẫn mất vài giây
  • Sẽ rất thú vị nếu có một phiên bản dùng io_uring

    • Có thể tránh copy và giảm overhead của system call bằng cách dùng buffer được chia sẻ trước với kernel
  • Việc blog mất khoảng 20 giây để tải là một tuyên bố khá táo bạo

  • Gần như mọi hình thức IPC đều "chậm"

    • Đây là cái giá hiệu năng được chấp nhận để đổi lấy sự an toàn
  • Ban đầu tôi không hiểu vì sao splice lại chậm đến vậy

    • Bài viết có chỉ ra vì sao nó chậm hơn vmsplice, nhưng chưa làm rõ nguyên nhân tại sao
    • Hẳn phải có lý do nào đó khiến nó không thể được tái triển khai bằng vmsplice