Crate bzip2 chuyển sang bản triển khai 100% Rust thay vì C
(trifectatech.org)- Crate
bzip20.6.0 đã chọnlibbz2-rs-sys, một bản triển khai thuật toán bzip2 bằng Rust, làm mặc định, loại bỏ phụ thuộc C đồng thời cải thiện cả tốc độ lẫn sự tiện lợi khi biên dịch chéo - bzip2 là một thuật toán cũ ít được dùng hơn, nhưng nhiều giao thức và thư viện vẫn phải hỗ trợ để tuân thủ đặc tả, nên nó vẫn nằm sâu trong cây phụ thuộc
- Bản triển khai Rust dùng ít chu kỳ CPU hơn khoảng 9,66~14,87% so với C khi nén, và khi giải nén cũng cải thiện 4,48~10,00% trên toàn bộ các bài kiểm thử
- Việc loại bỏ C giúp đơn giản hóa build cho WebAssembly, Windows, Android, và mặc định không xuất các symbol của
libbz2-rs-sys, giảm rủi ro xung đột symbol với các phụ thuộc khác - Trong quá trình audit, một lỗi logic off-by-one và một số giới hạn của fuzzer đã được sửa; các thư viện và ứng dụng cấp cao dùng
bzip2cũng có thể chạy MIRI
Thay đổi bản triển khai mặc định trong bzip2 0.6.0
- Crate
bzip20.6.0 dùnglibbz2-rs-sys, bản triển khai thuật toán bzip2 bằng Rust, làm mặc định - Khi loại bỏ phụ thuộc C hiện có, crate
bzip2trở nên nhanh hơn và dễ biên dịch chéo hơn - Crate
libbz2-rs-syscó thể được build dưới dạng thư viện động C để các dự án C cũng tận dụng được các cải tiến - Dù bzip2 hiện không còn được sử dụng nhiều, nhiều giao thức và thư viện vẫn phải hỗ trợ nó để tuân thủ đặc tả, và nó vẫn nằm sâu trong cây phụ thuộc của nhiều dự án
- Có thể xem chi tiết triển khai trong bài viết trước Translating bzip2 with c2rust
Kết quả cải thiện hiệu năng
- Bản triển khai Rust nhìn chung nhanh hơn bản triển khai C, và trong một số trường hợp có hiệu năng tương đương C
- Trong phạm vi đã biết, không có trường hợp nào chậm hơn đáng kể
- Trong benchmark nén, số chu kỳ CPU giảm so với C
sample3.reflevel 1:38.51M→33.53M, -14,87%silesia-small.tarlevel 1:3.43G→3.00G, -14,30%silesia-small.tarlevel 9:3.47G→3.17G, -9,66%levelcủa bzip2 chỉ lượng bộ nhớ làm việc được dùng và không ảnh hưởng nhiều đến hiệu năngsample3.refchỉ với level 1 đã cấp phát nhiều bộ nhớ hơn kích thước tệp, nên các level cao hơn ít liên quan
- Hiệu năng giải nén cũng được cải thiện trên toàn bộ các bài kiểm thử
sample3.bz2: -4,48%sample1.bz2: -8,63%sample2.bz2: -7,67%dancing-color.ps.bz2: -5,17%re2-exhaustive.txt.bz2: -7,65%zip64support.tar.bz2: -10,00%
- Trên máy benchmark macOS, đôi khi số liệu hiệu năng giải nén cho kết quả thấp
- Chưa xác định được nguyên nhân, và trên macOS khó vận hành công cụ có thể tự động hóa việc theo dõi hiệu năng như
perf
- Chưa xác định được nguyên nhân, và trên macOS khó vận hành công cụ có thể tự động hóa việc theo dõi hiệu năng như
Build và giảm xung đột symbol
- Việc biên dịch chéo các dự án Rust có phụ thuộc C thường chạy được ngay nhờ crate
cc, nhưng nếu thất bại thì có thể khó debug lỗi- Liên kết thư viện hệ thống cũng có thể tạo ra các vấn đề khó hiểu và khó tái hiện
- Việc biên dịch bzip2 sang WebAssembly đã gặp vấn đề từ lâu
- Khi loại bỏ phụ thuộc C và chỉ dùng mã Rust, các bản build WebAssembly, Windows, Android trở nên dễ chạy hơn
libbz2-rs-sysmặc định không export symbol- Khi dùng phụ thuộc C, cần export symbol để khối
externcủa Rust có thể tìm thấy - Tên đã export có thể xung đột khi một phụ thuộc khác khai báo cùng symbol
- Nếu dự án Rust cần export symbol, có thể bật bằng feature flag
- Khi dùng phụ thuộc C, cần export symbol để khối
Kết quả xác minh và audit
- Một bản triển khai bzip2 có hiệu năng cần một số mã unsafe, và để tái tạo giao diện C bằng Rust thì cần thêm nhiều mã unsafe hơn
- Mã này có thể chạy trong MIRI
- Các thư viện cấp cao hoặc ứng dụng dùng
bzip2giờ cũng có thể chạy bằng MIRI
- Audit đã phát hiện một lỗi logic off-by-one và sửa một số giới hạn của fuzzer
- Không có phát hiện quan trọng nào khác
- Audit do Radically Open Security thực hiện, và báo cáo đầy đủ có thể xem tại PDF báo cáo audit
- Công việc lần này nhận được sự hỗ trợ từ Alex Crichton, maintainer của crate
bzip2, Radically Open Security với hoạt động audit và chuyên môn, cùng NLnet Foundation, đơn vị tài trợ thông qua e-Commons Fund
Chưa có bình luận nào.