2 điểm bởi GN⁺ 2023-11-30 | 1 bình luận | Chia sẻ qua WhatsApp
  • Điểm khởi đầu là một báo cáo rằng việc đọc tệp trong binding Python của Apache OpenDAL chậm hơn open().read() tích hợp sẵn của Python, nhưng nút thắt không nằm ở bản thân OpenDAL hay PyO3
  • Trong benchmark đọc tệp 64MiB, python-fs-read được đo khoảng 15~19ms, còn Rust std::fs và bản triển khai C khoảng 23ms, khiến Rust/C trông có vẻ chậm hơn Python
  • Khi lần theo strace, eBPF, perf, khác biệt được liên hệ với offset của bộ đệm đích của syscall read bên trong trang bộ nhớ, và hiện tượng giảm hiệu năng được tái hiện quanh 0x10
  • Hiện tượng tương tự được xác nhận trên các dòng AMD Ryzen 9 5900X, Ryzen 7 5700X, Ryzen 9 5900HX; hiệu năng thực thi rep movsb bên trong _copy_to_iter của kernel là manh mối chính
  • Không phải Python vốn nhanh hơn, mà kết quả này do lỗi CPU liên quan đến FSRM/rep movsb trên AMD Zen 3 và sự ngẫu nhiên của offset bộ nhớ; cải thiện khi dùng jemalloc cũng không phải do bản thân allocator, mà do offset khác

Benchmark kỳ lạ bắt đầu từ binding Python của OpenDAL

  • Apache OpenDAL là lớp truy cập dữ liệu để đọc và ghi dữ liệu theo cách thống nhất trên nhiều dịch vụ lưu trữ, và binding Python được cung cấp thông qua PyO3
  • Một người dùng báo rằng đoạn mã đọc tệp 150MB bằng binding Python của OpenDAL chậm hơn đọc tệp tích hợp sẵn của Python
    • open(...).read() tích hợp sẵn của Python, 100 lần: 4.470868484000675
    • Binding Python của OpenDAL, 100 lần: 8.993250704006641
  • Ngay cả khi đơn giản hóa thành đọc tệp 64MiB, binding OpenDAL vẫn chậm hơn
    • python-fs-read: trung bình 15.9ms
    • python-opendal-read: trung bình 32.9ms
    • Đọc tích hợp sẵn của Python được đo nhanh hơn binding OpenDAL 2.07 lần

Lần theo xuống Rust OpenDAL rồi đến std::fs

  • Khi triển khai cùng logic bằng dịch vụ fs của OpenDAL trong Rust, nó vẫn chậm hơn đọc tích hợp sẵn của Python
    • rust-opendal-fs-read: trung bình 23.8ms
    • python-fs-read: trung bình 15.6ms
    • Đọc tích hợp sẵn của Python được đo nhanh hơn triển khai Rust OpenDAL 1.52 lần
  • Vì dịch vụ fs của OpenDAL sử dụng std::fs của Rust, một bản triển khai riêng dựa trên std::fs đã được viết để kiểm tra chi phí của chính OpenDAL
  • Với triển khai trực tiếp bằng Rust std::fs, xu hướng tương tự vẫn tiếp diễn
    • rust-std-fs-read: trung bình 23.1ms
    • python-fs-read: trung bình 15.2ms
    • Đọc tích hợp sẵn của Python được đo nhanh hơn Rust std::fs 1.52 lần

Syscall và mmap nhìn từ strace

  • Phân tích bằng strace cho thấy cả Rust lẫn Python đều dùng mmap cho các cấp phát bộ đệm lớn
  • Khi chạy Rust std::fs, luồng xử lý là mở /tmp/file, đọc 64MiB một lần, gọi read để kiểm tra EOF rồi đóng tệp
  • Đọc tích hợp sẵn của Python thực thi nhiều syscall hơn như newfstatat, ioctl, lseek, nhưng tổng thời gian lại ngắn hơn
  • Lệnh gọi mmap(NULL, 67112960, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) được dùng cho cấp phát bộ nhớ ẩn danh, không phải ánh xạ tệp
    • 67112960 là kích thước 64MiB cộng thêm 4KiB
    • MAP_ANONYMOUS nghĩa là cấp phát bộ nhớ không liên quan đến tệp
  • Bản build mặc định x86_64-unknown-linux-gnu của Rust dùng malloc của glibc, và glibc có thể dùng mmap cho các cấp phát lớn

Rust nhanh hơn với jemalloc và kết luận tạm thời bị đảo ngược

  • Khi đổi allocator toàn cục của Rust sang jemallocator::Jemalloc, Rust trở nên nhanh hơn Python
    • rust-std-fs-read-with-jemalloc: trung bình 9.7ms
    • python-fs-read: trung bình 15.8ms
    • Triển khai Rust dùng jemalloc được đo nhanh hơn Python 1.64 lần
  • Ở thời điểm này, nguyên nhân trông có vẻ là mmap hoặc allocator bộ nhớ mặc định, nhưng diễn giải sau đó đã được chỉnh lại trong bản cập nhật
  • Theo cập nhật ngày 2023-12-01, khác biệt không phải do jemalloc, pymalloc, mimalloc vốn nhanh hơn glibc malloc
  • Khác biệt thực sự đến từ offset trong trang của bộ đệm mà allocator tạo ra
    • rust-std-fs-read: đọc tại offset 0x10 từ địa chỉ bắt đầu của mmap
    • rust-std-fs-read-with-jemalloc: đọc tại offset 0x740 từ địa chỉ bắt đầu của mmap
  • Vùng có vấn đề được thu hẹp còn phạm vi 0x00..0x10 bên trong trang, và cũng có thể tái hiện cùng vấn đề với jemalloc

Vấn đề có tính tái hiện theo thiết bị hơn là theo cấu hình phần mềm

  • Khi thảo luận tiếp diễn, người ta xác nhận rằng hiện tượng Rust chậm hơn Python đặc biệt rõ trên máy của tác giả
  • CPU của tác giả là AMD Ryzen 9 5950X 16-Core Processor, với cấu hình bộ nhớ DDR4 3200 MT/s 16GB DIMM
  • Ngay cả khi thay đổi nhiều cấu hình, chênh lệch hiệu năng tương đối vẫn không biến mất
    • Bật lại mitigations=off của Linux kernel cũng không làm kết quả thay đổi
    • Khi đổi Transparent Hugepage giữa always, madvise, never, giá trị tuyệt đối thay đổi nhưng tỷ lệ tương đối vẫn giữ nguyên
    • Dùng core_affinity để ghim vào một lõi CPU cụ thể cũng cho kết quả như vậy
  • Đo độ trễ syscall read dựa trên eBPF cũng cho thấy phía Rust chậm hơn
    • Python read file: 8,134,049ns
    • Rust std::fs read file: 24,636,975ns
  • Quan sát cho thấy khó có thể giải thích khác biệt chỉ bằng OpenDAL, PyO3 hay thư viện chuẩn Rust; thời gian đã bị kéo giãn ngay từ cấp syscall

Manh mối offset bộ nhớ lộ ra trong bản triển khai C

  • Khi triển khai cùng thao tác đọc tệp 64MiB bằng C fopen/malloc/fread, nó cũng chậm hơn Python
    • c-fs-read: trung bình 23.8ms
    • python-fs-read: trung bình 19.1ms
    • Đọc tích hợp sẵn của Python được đo nhanh hơn triển khai C 1.25 lần
  • Khi kiểm tra địa chỉ con trỏ bằng strace -e raw=read,mmap, offset bắt đầu bộ đệm của C và Python khác nhau
    • C: read tại offset 0x10 từ địa chỉ trả về của mmap
    • Python: read tại offset 0x30 từ địa chỉ trả về của mmap
  • Khi điều chỉnh offset trong triển khai C theo cùng cách, hiệu năng cải thiện đáng kể
    • c-fs-read-with-offset: trung bình 8.9ms
    • Nhanh hơn Python 2.15 lần, và nhanh hơn triển khai C ban đầu 2.68 lần
  • Vấn đề này cũng được tái hiện trên AMD Ryzen 9 5900XAMD Ryzen 7 5700X
  • Trong chủ đề Std::fs::read slow? của cộng đồng Rust, hiện tượng tương tự cũng được báo cáo, và mối liên hệ giữa offset vùng nhớ với hiệu năng syscall đã được chỉ ra

Phân tích perf chỉ tới rep movsb

  • Một nhà phát triển kernel đã tái hiện c-fs-read và phiên bản có áp dụng offset trên AMD Ryzen 9 5900HX, rồi phân tích bằng perf
  • Tùy có offset hay không, các giá trị L1-dcache-prefetchesL1-dcache-loads khác nhau rất lớn
    • Không có offset: L1-dcache-loads khoảng 127,845,213, L1-dcache-prefetches khoảng 1,843,493
    • Có offset: L1-dcache-loads khoảng 13,965,813, L1-dcache-prefetches khoảng 395,578
  • Điểm nóng nằm trên đường đi read của kernel, theo chuỗi shmem_file_read_itercopy_page_to_iter_copy_to_iter
  • Assembly cốt lõi bên trong _copy_to_iterrep movsb, và phần lớn mẫu tập trung vào lệnh này
  • Trong phân tích sau đó, manh mối quan trọng hơn được tổng kết là hiện tượng rep movsb có hiệu năng kém với dữ liệu được căn chỉnh theo trang, và tốt hơn khi việc căn chỉnh theo trang bị phá vỡ, thay vì bản thân L1 prefetch

FSRM và vấn đề AMD Zen 3

  • Báo cáo lỗi Ubuntu glibc được chia sẻ, Terrible memcpy performance on Zen 3 when using rep movsb, cũng đề cập đến vấn đề hiệu năng của rep movsb
  • Ví dụ trong báo cáo đó giải thích rằng với bản sao 2113 byte, đường đi rep movsb cho khoảng 3.2GB/s, nhưng nếu đổi kích thước thành 2111 byte thì tăng lên hơn 100GB/s
  • FSRM là viết tắt của Fast Short REP MOV, một tính năng nhằm làm cho rep movsbrep movsd nhanh hơn
  • FSRM bắt đầu từ Intel và cũng được đưa vào AMD; trên các CPU tuyên bố hỗ trợ, glibc mặc định sử dụng FSRM
  • Vì vậy, không phải Python vốn nhanh hơn C/Rust, mà là do lỗi CPU AMD khiến đường đọc của C/Rust chậm đi ở các offset bộ nhớ cụ thể

Cập nhật: AMD có biết hay không và phản ứng của glibc

  • Theo cập nhật ngày 2023-12-01, có vẻ AMD đã biết lỗi này từ năm 2021
  • Sau khi bài viết được công bố, nhiều độc giả đã gửi liên kết cho AMD, nên có thể xem là AMD đã biết vấn đề này
  • Tác giả cho rằng AMD nên chịu trách nhiệm sửa lỗi này trong amd-ucode, nhưng theo thông tin chưa được xác nhận, việc sửa bằng amd-ucode trên Zen 3 có thể khó khăn
  • Hy vọng thực tế là glibc sẽ vô hiệu hóa FSRM khi cần
  • Phía glibc đang tiến hành công việc x86: Improve ERMS usage on Zen3

Mã tái hiện và tài liệu liên quan

1 bình luận

 
GN⁺ 2023-11-30
Ý kiến trên Hacker News
  • Có tới hai cờ tính năng CPU chuyên dụng cho biết REP STOS/MOV nhanh và có thể dùng làm chuỗi lệnh ngắn cho memset/memcpy
    Nỗi khổ phải viết lại thủ công các routine tối ưu hóa cho mỗi thế hệ CPU mới đã kéo dài hàng chục năm, vậy mà đến giờ vẫn còn tình trạng này; tôi tự hỏi chẳng phải nó nên nằm trong bộ kiểm thử timing của các nhà cung cấp CPU sao

    • Hoàn toàn chỉ là suy đoán, nhưng có vẻ cũng có thể là ảnh hưởng của một bản sửa lỗi được đưa vào bằng cập nhật microcode vào phút chót hoặc sau khi phát hành
      Có thể rep movs nhanh với căn chỉnh theo trang đã gặp vấn đề, hoặc dễ bị một kiểu tấn công nào đó nên bị vô hiệu hóa
    • Nếu tôi hiểu đúng thì không rõ điều này có nghĩa là phải tạo hai file thực thi cho mỗi bản build tại một thời điểm biên dịch cụ thể, hay là phải biên dịch trên phần cứng cụ thể
      Tôi không biết bản sửa nên theo hướng nào, có cần thứ như kiểm tra runtime hay không
    • Rất dễ nghĩ rằng nhà cung cấp CPU là bên hiểu CPU của họ rõ nhất
      Nếu có một triển khai “phần mềm” nhanh hơn, tôi thắc mắc vì sao REP MOVS ít nhất không được làm để thực hiện cùng việc đó trong microcode
  • Bug glibc liên quan nằm ở đây. Tuy nhiên trường hợp này là Zen 4: https://sourceware.org/bugzilla/show_bug.cgi?id=30994

  • Ban đầu đọc bài tôi đã chuẩn bị cười nhạo vì nghĩ tác giả dùng sai std::fs, nhưng thực ra đây lại là một bài viết thú vị, kéo theo một hố thỏ debugging và một bí ẩn
    Viết hay và rất thú vị

    • Đúng là một bài rất hay. Cách debug bằng việc tạo chương trình thử nghiệm rồi bóc tách từng lớp rất thông minh, kết luận thì thú vị và ngoài dự đoán, bài viết cũng rõ ràng nên dễ theo dõi
  • Tiền đề hơi gây nhầm lẫn. Đây không phải là so sánh code Python thuần với code C/Rust native, mà là so sánh phương thức đọc file của Python, một wrapper Python trên code native, với OpenDAL, một wrapper khác trên code native
    Việc có chênh lệch hiệu năng vẫn thú vị, nhưng diễn đạt là “chậm hơn Python” thì khá kỳ lạ. Có phải người ta kỳ vọng toàn bộ thư viện chuẩn Python được viết bằng Python thuần không? Ngược lại, tôi còn nghĩ các triển khai hàm trong thư viện chuẩn Python là native và được tối ưu hóa cao ở mức riêng lẻ
    Việc kết luận liên quan đến cách code native hoạt động thì không gây ngạc nhiên, nhưng đáp án cụ thể lại bất ngờ. Chỉ là phần mở đầu hơi gây lẫn lộn, còn bản thân bài viết thì rất thú vị
    Ngoài ra, tiêu đề “C is slower than Python with specified offset” với người bản ngữ sẽ được hiểu là “C vẫn chậm hơn Python ngay cả khi đã chỉ định offset”. Thực tế ý lại ngược lại: khi chỉ định cho C cùng offset đã dùng trong Python thì C trở nên nhanh hơn

    • Tôi lại không hiểu lắm vì sao nó gây nhầm lẫn
      Một tác vụ đơn giản như đọc file mà thư viện chuẩn Rust chậm hơn thư viện chuẩn Python là chuyện đáng ngạc nhiên. Ngay cả khi biết các lời gọi thư viện chuẩn Python kiểu này được viết bằng C, ta vẫn kỳ vọng lời gọi thư viện chuẩn Rust có tốc độ tương tự
      Vì vậy thông thường người ta sẽ đoán là dùng sai cách hoặc thư viện chuẩn Rust có hành vi lạ, nhưng lần này cả hai đều không phải; đó là một vách hiệu năng xuất hiện trên phần cứng cụ thể tùy theo căn chỉnh cấp phát
      Ta có thể kỳ vọng đọc hệ thống file trong Python được tối ưu tốt, nhưng cũng nghĩ Rust cũng sẽ như vậy; do đó việc phía Rust chậm hơn nhiều là điều đáng ngạc nhiên, và càng ngạc nhiên hơn vì nó phụ thuộc vào phần cứng và allocator
    • Tôi không hiểu vì sao Python khi chậm thì bị chê là ngôn ngữ chậm, còn khi nhanh thì lại không được công nhận với lý do “đó không phải Python thật”
      Nếu code viết bằng Python chạy nhanh thì với tôi đó là Python nhanh. Việc phần triển khai được viết bằng ngôn ngữ khác hay vì lý do nào khác không quan trọng lắm
    • Tôi không rõ vì sao lại có lý do để kỳ vọng nó “được tối ưu hóa cao ở mức riêng lẻ”
      Những gì xảy ra trong bài gốc gần như thuần túy là tình cờ. Code C của CPython thậm chí còn không bận tâm đến tính nhất quán const, có nhiều cấp phát bộ nhớ động và nhiều lời gọi phụ/trợ tiện ích. Ngay cả các phép toán số học cũng cấp phát bộ nhớ động
      Nếu từng làm việc với CPython, thường bạn sẽ không kỳ vọng hiệu năng tốt. Khi muốn cải thiện hiệu năng, bạn sẽ muốn đi vòng qua các tính năng nó cung cấp
      Ngoài ra Python không có chuẩn, nên nói chặt chẽ thì cũng không có thư viện chuẩn; các thư viện được phân phối kèm phần lớn được viết bằng Python. Một số được viết bằng C, nhưng trong số code C đó cũng có khá nhiều phần về cơ bản là chuyển cơ học code Python sang C. Ví dụ triển khai tìm kiếm nhị phân của Python ban đầu được viết bằng Python, sau đó được dịch sang C bằng Python C API
      Điều có thể kỳ vọng chỉ là các tính năng ánh xạ đơn giản tới chức năng của hệ điều hành sẽ có wrapper tương đối mỏng. Tức là đọc file về bản chất đi thẳng vào giao diện hệ thống, nên sẽ không cần nhiều code binding
    • Cảm ơn đã chỉ ra. Tôi đã sửa tiêu đề
    • Tiền đề là nếu dùng những câu kiểu “Python nhanh hơn Rust” thì dù không đúng sự thật vẫn kéo được pageview
      Sau khi những bài tương tự xuất hiện hàng chục lần, mọi người đều đã nhận ra điều đó
  • Bài viết tự thân đã rất xuất sắc và có nhiều thông tin thú vị liên quan đến vấn đề này
    Tuy nhiên, điều khiến tôi quan tâm và lo ngại hơn là vấn đề được báo cáo, ghi nhận như thế nào, và việc giao tiếp được xử lý ra sao
    Báo cáo được thực hiện trên Discord, một môi trường độc quyền, không được lập chỉ mục, khó tìm kiếm và cũng không được lưu trữ lâu dài. Thảo luận diễn ra trên Discord và Telegram, mà trong bối cảnh này Telegram có khi còn tệ hơn
    Bài blog này và kho GitHub là tất cả dấu vết còn lại. Nếu Xuanwo không viết lên blog thì nó đã biến mất trong dòng thời gian rồi. Một tình huống khá thú vị

    • Đúng là nền tảng độc quyền và điều đó không tốt. Nhưng lời chỉ trích rằng nó không được lập chỉ mục hay không tìm kiếm được thì khó thuyết phục
      Hầu như không có trình nhắn tin nào mặc định lập chỉ mục/tìm kiếm các log có thể truy cập công khai. Không phải máy chủ IRC nào cũng cung cấp log công khai, các nhóm Matrix cũng vậy. Tôi không hiểu vì sao lại cho rằng các cuộc thảo luận ở đó sẽ không biến mất trong dòng thời gian
      Lý do có thể cung cấp log công khai không phải vì nó không độc quyền, mà vì có API cho phép ghi log. Telegram cũng có API như vậy, và nhóm thảo luận của chúng tôi cũng có log có thể tìm kiếm tại đây: https://luoxu-web.vercel.app/#g=1264662201
      Việc không lập chỉ mục công khai chủ yếu là vì quyền riêng tư, chứ không phải vì nền tảng đó độc quyền
    • Đây chính là lý do mỗi khi tiếc nuối sự suy tàn của USENET, tôi không chấp nhận câu trả lời kiểu “giờ đã có Discord rồi còn gì”
      Ngày trước, mọi bài viết đều có thể được tìm kiếm gọn gàng trên DejaNews, rồi sau này là Google
      Các trao đổi quan trọng của những dự án mã nguồn mở quan trọng như stack Internet/WWW và các công cụ, thư viện lập trình cốt lõi cần quay lại với tiêu chuẩn mở
  • Đây là bài thú vị nhất tôi đọc trong tuần này. Tổng hợp rất tốt

  • Việc hiển nhiên cần làm có vẻ là gửi một bản vá cho phương thức kernel copy_user_generic
    Nếu phát hiện CPU có vấn đề và gây ra lỗi làm chậm căn chỉnh bộ nhớ, chỉ cần khiến nó dùng một triển khai sao chép bộ nhớ khác là được

    • Không hẳn là hiển nhiên. Nếu có thể sửa bằng microcode, có vẻ tốt hơn là để mọi người dùng microcode đã cập nhật, thay vì rải mã sửa lỗi cho một vấn đề về cơ bản có thể vá bằng phần mềm khắp kernel
      Một bản sửa đủ để người không có kinh nghiệm kernel chấp nhận sẽ không hề đơn giản. Quan trọng hơn, cách kích hoạt workaround cũng không rõ ràng. Có lẽ tốt nhất là đo ở thời điểm boot, còn nếu không thì khá mơ hồ làm sao biết được model và stepping nào bị ảnh hưởng
    • Đây không phải là một sửa đổi nhỏ. AMD cần tìm ra vì sao aliasing bị hỏng ở các địa chỉ gần căn chỉnh trang, nên khả năng cao bản sửa sẽ nằm ở phía microcode
      Biện pháp giảm nhẹ bằng phần mềm cũng sẽ phức tạp. Lý do là kernel thực ra không thể dùng các lệnh vector thường được dùng ở đường thay thế khi không thể dùng ERMS
  • jemalloc là allocator mặc định của Rust cho đến năm 2018
    https://internals.rust-lang.org/t/jemalloc-was-just-removed-...

  • Tôi thắc mắc về đoạn “lập trình viên Rust có thể cân nhắc chuyển sang jemallocator để cải thiện hiệu năng”
    Không rõ liệu ai cũng có thể gần như miễn phí nhận được cải thiện hiệu năng hay có điểm gì cần lưu ý. Tôi cũng tò mò liệu codebase C có hưởng lợi được không, và liệu đây có phải là phần hiệu năng hiện đang bị bỏ lỡ hay không

    • Cần biết rằng khi dùng jemalloc, do MADV_FREE sẽ phát sinh vấn đề về khả năng quan sát. htop sẽ không còn hiển thị chính xác lượng bộ nhớ thực sự đang được sử dụng
      https://github.com/jemalloc/jemalloc/issues/387#issuecomment...
      https://gitlab.haskell.org/ghc/ghc/-/issues/17411
      Hiện có vẻ jemalloc gọi MADV_DONTNEED 10 giây sau MADV_FREE: https://github.com/JuliaLang/julia/issues/51086#issuecomment...
      Vì vậy, nó có “sửa” vấn đề này, nhưng sẽ có một độ trễ gây nhầm lẫn giữa thời điểm giải phóng bộ nhớ và thời điểm có thể quan sát điều đó trong htop
      Tuy nhiên, theo https://jemalloc.net/jemalloc.3.html, có thể đặt opt.muzzy_decay_ms = 0 để loại bỏ độ trễ
      Dù vậy, tác giả của musl vẫn dè dặt về việc dùng jemalloc làm mặc định: https://www.openwall.com/lists/musl/2018/04/23/2
      Ý chính là có các vấn đề như phình to nghiêm trọng, làm suy yếu ASLR, và tối ưu hóa thiên về việc làm nhanh nhất có thể mà không quan tâm đến mức dùng bộ nhớ. Các giá trị tinh chỉnh trên có thể giảm nhẹ phần nào, nhưng xu hướng tổng thể là tập trung vào hiệu năng hay mức dùng bộ nhớ nhiều khả năng vẫn là một sự đánh đổi
    • Tôi cho rằng đó là hiệu năng gần như miễn phí đang bị bỏ lỡ. Cái giá phải trả là kích thước binary tăng thêm một chút
      Không nhất thiết lúc nào cũng nhanh hơn trong mọi tình huống, nhưng gần như trong đa số trường hợp sẽ nhanh hơn. Rust trước đây cũng từng dùng jemalloc làm mặc định, nhưng đã đổi vì có người thấy lựa chọn mặc định đó là bất ngờ
    • Chuyển sang allocator không phải mặc định không phải lúc nào cũng làm tăng hiệu năng
      Nó phụ thuộc rất nhiều vào workload, nên cần profiling và benchmarking. Dù vậy, các ngôn ngữ cấp thấp như C/C++/Rust nên có khả năng chọn những allocator như vậy
      Một điểm cần lưu ý là kích thước binary. Allocator tùy chỉnh sẽ thêm byte vào file thực thi
    • Rust trước đây từng dùng jemalloc làm mặc định, nhưng khoảng năm 2018 đã quay lại dùng malloc của hệ thống[0]
      Hiện Rust có trait GlobalAlloc và thuộc tính #[global_allocator], nên nếu ứng dụng muốn thì có thể dùng jemalloc làm allocator. Tôi không rõ người dùng có thể ghi đè bằng cách như LD_PRELOAD hay không
      jemalloc không phải lúc nào cũng là lựa chọn tốt nhất cho mọi workload và use case. Allocator hệ thống thường còn xa mới hoàn hảo, nhưng ít nhất nó đã được kiểm thử rộng rãi như một allocator đa dụng
      [0] https://github.com/rust-lang/rust/issues/36963
    • Hiệu năng không phải là thang đo một chiều nơi chương trình di chuyển từ “chậm” sang “nhanh”. Luôn có các yếu tố khác cùng tác động
      jemalloc có thể là lựa chọn phù hợp cho một số ứng dụng, nhưng trong trường hợp khác, allocator khác có thể nhanh hơn. Hoặc dù chậm hơn, nó có thể phù hợp hơn với các mục tiêu như ít bộ nhớ bẩn hơn, khả năng quan sát tốt hơn, hay một số bảo đảm bảo mật cụ thể
  • Tôi đã gửi nội dung này cho những người phù hợp

    • Ý là đã gửi cho phía AMD à?