OpenBSD cho thấy lợi thế tốc độ tạo socket nhanh gấp 10 lần so với Linux do nghẽn cổ chai đồng bộ hóa RCU

Nhóm Cộng đồng BigGo
OpenBSD cho thấy lợi thế tốc độ tạo socket nhanh gấp 10 lần so với Linux do nghẽn cổ chai đồng bộ hóa RCU

Một bài kiểm tra hiệu suất gần đây đã tiết lộ khoảng cách hiệu suất đáng ngạc nhiên giữa OpenBSD và Linux khi tạo network socket trong các ứng dụng đa luồng. Bài kiểm tra này, bao gồm hai luồng mỗi luồng tạo 256 TCP socket, cho thấy OpenBSD hoàn thành tác vụ trong khoảng 2-6 mili giây trong khi Linux mất 17-26 mili giây - chênh lệch hiệu suất nhanh hơn tới 10 lần.

Kết quả So sánh Hiệu suất:

  • Hiệu suất Linux: 17-26 mili giây (0.017770s - 0.026309s)
  • Hiệu suất OpenBSD: 2-6 mili giây (0.002326s - 0.006096s)
  • Chênh lệch Tốc độ: Nhanh hơn tới 10 lần trên OpenBSD
  • Kịch bản Kiểm tra: 2 luồng, mỗi luồng tạo 256 socket TCP (tổng cộng 512 bộ mô tả tệp)

Nguyên nhân gốc rễ: Mở rộng bảng File Descriptor

Sự khác biệt về hiệu suất bắt nguồn từ cách mỗi hệ điều hành xử lý việc mở rộng bảng file descriptor khi có nhiều luồng tham gia. Trong Linux, bảng file descriptor bắt đầu với 256 slot theo mặc định. Khi hai luồng tạo 256 socket mỗi luồng (tổng cộng 512 file descriptor), hệ thống phải mở rộng bảng này ở giữa quá trình.

Trong quá trình mở rộng này, kernel của Linux kiểm tra xem có nhiều luồng chia sẻ cùng một bảng file descriptor hay không. Khi phát hiện truy cập chia sẻ (được chỉ ra bởi số lượng tham chiếu lớn hơn 1), nó gọi một hàm có tên synchronize_rcu() để đảm bảo an toàn luồng. Hàm này chờ đợi một chu kỳ grace period RCU đầy đủ hoàn thành, có thể mất nhiều mili giây và tạo ra nghẽn cổ chai hiệu suất được quan sát.

RCU (Read-Copy-Update) là một phương pháp đồng bộ hóa cho phép nhiều luồng đọc dữ liệu một cách an toàn trong khi một luồng cập nhật nó, nhưng yêu cầu thời gian chờ để đảm bảo tất cả các reader đã hoàn thành.

Chi tiết kỹ thuật:

  • Kích thước bảng FD mặc định của Linux: 256 slot
  • Điều kiện kích hoạt bottleneck: Mở rộng bảng file descriptor khi reference count > 1
  • Phương pháp đồng bộ hóa của Linux: RCU (Read-Copy-Update) với các lệnh gọi synchronize_rcu()
  • Phương pháp đồng bộ hóa của OpenBSD: Traditional read-write locks
  • Giải pháp thay thế: Mở rộng trước bảng FD bằng cách sử dụng dup2(0, 666) trước khi tạo thread

Cách tiếp cận đơn giản hơn của OpenBSD

OpenBSD sử dụng một cách tiếp cận hoàn toàn khác. Thay vì sử dụng đồng bộ hóa RCU, nó dựa vào các read-write lock truyền thống khi sửa đổi bảng file descriptor. Phương pháp này tránh được những độ trễ đồng bộ hóa dài gây ra vấn đề cho Linux trong tình huống cụ thể này, dẫn đến thời gian tạo socket nhanh hơn nhiều.

Bài kiểm tra cũng chứng minh một cách giải quyết cho vấn đề của Linux. Bằng cách mở rộng trước bảng file descriptor sử dụng dup2(0, 666) trước khi tạo các luồng bổ sung, penalty hiệu suất sẽ biến mất vì bảng không còn cần mở rộng trong quá trình tạo socket.

Góc nhìn cộng đồng và ý nghĩa rộng lớn hơn

Khám phá này đã khơi dậy những cuộc thảo luận thú vị về sự đánh đổi trong thiết kế hệ điều hành. Trong khi bài kiểm tra này cho thấy lợi thế của OpenBSD trong một tình huống cụ thể, các thành viên cộng đồng lưu ý rằng Linux thường vượt trội hơn OpenBSD trong hầu hết các workload khác với biên độ đáng kể. Hệ thống RCU gây ra sự chậm trễ đặc biệt này thực sự mang lại lợi ích trong nhiều tình huống khác.

Một tiêu đề tốt hơn: một chương trình kiểm tra bệnh lý được thiết kế cho Linux không kích hoạt hành vi bệnh lý trên OpenBSD

Bài kiểm tra này làm nổi bật cách các quyết định thiết kế kernel khác nhau có thể tạo ra các đặc tính hiệu suất bất ngờ. Trong khi cách tiếp cận RCU của Linux mang lại lợi thế trong nhiều tình huống, nó có thể tạo ra nghẽn cổ chai trong các trường hợp edge case cụ thể như phân bổ file descriptor nhanh trong các chương trình đa luồng.

Những phát hiện này nhắc nhở rằng hiệu suất hệ điều hành phụ thuộc rất nhiều vào workload, và các bài kiểm tra đơn giản có thể tiết lộ những khác biệt kiến trúc thú vị giữa các hệ thống mà nếu không có thể không được chú ý.

Tham khảo: Is OpenBSD 10x faster than Linux?