2009-12-01 29 views
30

Tôi đang xây dựng một máy chủ Linux hiệu năng cao (dựa trên ổ cắm không bị chặn, và đĩa không đồng bộ IO [dựa trên io_submit/io_getevents/eventfd]). Một số tiêu chuẩn của tôi cho thấy cách tôi xử lý ổ cắm không đủ hiệu quả cho các yêu cầu của tôi. Đặc biệt, tôi quan tâm đến việc lấy dữ liệu từ bộ đệm vùng người dùng đến thẻ mạng, và từ thẻ mạng trở lại bộ đệm vùng người dùng (hãy bỏ qua cuộc gọi sendfile ngay bây giờ). Từ những gì tôi hiểu, hãy gọi đọc/ghi trên ổ cắm Linux không chặn không hoàn toàn không đồng bộ - hệ thống chặn cuộc gọi trong khi nó sao chép bộ đệm từ vùng người dùng đến hạt nhân (hoặc cách khác xung quanh), và chỉ sau đó trở lại. Có cách nào để tránh tình trạng nghe lén này trong Linux không? Đặc biệt, có một cuộc gọi viết không đồng bộ hoàn toàn mà tôi có thể thực hiện trên một socket sẽ trả về ngay lập tức, DMA bộ đệm vùng người dùng vào thẻ mạng khi cần thiết và báo hiệu/thiết lập một sự kiện/etc. hoàn thành? Tôi biết Windows có một giao diện cho điều này, nhưng tôi không thể tìm thấy bất cứ điều gì về điều này trong Linux.Ổ cắm Linux hiệu quả (DMA/zero-copy)

Cảm ơn!

Trả lời

1

AFAIK bạn đang sử dụng các cuộc gọi hiệu quả nhất khả dụng nếu bạn không thể sử dụng sendfile (2). Các khía cạnh khác nhau của mã mạng hiệu suất cao hiệu quả được bao phủ bởi The C10K problem

19

Có một số cuộc nói chuyện về hạt nhân Linux gần đây về việc cung cấp API cho một thứ gì đó dọc theo các dòng này, nhưng điểm gắn kết là bạn không thể DMA từ bộ đệm không gian người dùng chung vào thẻ mạng, bởi vì:

  • Dữ liệu tiếp giáp trong không gian địa chỉ tuyến tính của người dùng có thể không tiếp giáp trong bộ nhớ vật lý, đó là vấn đề nếu card mạng không phân tán DMA;
  • Trên nhiều máy, không phải tất cả địa chỉ bộ nhớ vật lý đều là "DMA-khả năng". Hiện tại không có cách nào cho một ứng dụng không gian người dùng để yêu cầu cụ thể bộ đệm DMA.

On hạt nhân gần đây, bạn có thể thử sử dụng vmsplicesplice với nhau để đạt được những gì bạn muốn - vmsplice trang (với SPLICE_F_GIFT) mà bạn muốn gửi vào một đường ống, sau đó splice họ (với SPLICE_F_MOVE) từ các đường ống vào cái ổ cắm.

+1

Cảm ơn! Bạn có một linh cảm về cách hiệu quả này sẽ được đọc/ghi? Nói chung, có hướng dẫn "phương pháp hay nhất" ở đâu đó cho loại nội dung này không? Phải mất nhiều ngày để sàng lọc thông qua tất cả các API bỏ phiếu và báo hiệu, và sau đó thêm thời gian để chuẩn nó tất cả trước khi tôi tìm thấy một thực hành tốt nhất cho ghép nối ổ cắm và async IO. Nó sẽ thực sự giúp đỡ để tìm một hướng dẫn thực hành tốt nhất ổ cắm. Có trang vấn đề C10K, nhưng hầu hết các thông tin có nhiều năm tuổi (đó là tuổi trong thời gian hạt nhân), và thường rất không thuyết phục. –

+2

'splice' và bạn bè là khá mới, vì vậy tôi không chắc chắn nếu có bất kỳ loại" thực hành tốt nhất "hướng dẫn cho họ được nêu ra. Chúng phải có độ trễ khá thấp và không sao chép nếu có thể - đó là toàn bộ điểm của chúng. Bạn có thể thử hỏi trên danh sách gửi thư linux-net và/hoặc linux-kernel. – caf

+2

1,5 năm trôi qua kể từ khi các bài đăng này, bất kỳ sự phát triển mới nào trong lĩnh vực này? @caf: bạn có thể làm điều này với 'splice' không? –