2017-04-06 59 views
0

我正在使用udp套接字在實時環境中。我目前使用的標準套接字函數sendto()需要相當多的時間。我讀過可以使用零拷貝,如果我理解的很好,可以避免通過從用戶/內核環境複製文件來增加額外的時間。但是,我看到sendfile()只允許從一個文件描述符複製到另一個文件描述符。我看不到如何使用它發送UDP數據包,在我的情況下這是一個緩衝區。所以我的問題是:使用sendfile代替發送到零拷貝udp套接字

  1. 它甚至可以使用sendfile()發送UDP數據包?
  2. 如果是這樣,這樣做的正確方法是什麼?

編輯

我工作的實時平臺,在這裏我有幾個操作加上在插座上的發送。所有這些不應該超過1ms。我嘗試過三款機器,第一款擁有3.4GHz的4核心,2.3GHz的8核心和1.4GHz的4核心。第一個發送一個720字節的數據包需要不到1μs。而另外兩個則在6到9μs之間。我正在使用Linux低延遲內核,並取消了所有CPU電源管理功能,因此所有CPU都處於最高頻率。

我注意到,如果sendto()所花的時間大於6μs,平臺根本無法工作。另一個精度,我有幾個線程並行運行。所以也許只是在sendto()尚未完成時CPU正在處理其他線程。我想知道這是可能的,在進程中停止sendto()做其他事情。

這就是爲什麼我試圖找到其他解決方案來做優化的地方,我認爲使用sendfile()會避免額外的時間來保存。

+0

在Linux(以及Unixy世界的其餘部分)中,什麼是*「套接字」?它是一個*描述符*。僅僅因爲一些文檔說「文件」描述符並不意味着它必須是一個實際的「文件」。否則整個'sendfile'調用幾乎是無用的,如果它可以做的只是複製文件。 –

+0

@Someprogrammerdude。謝謝。我不太熟悉描述符/指針/之間的區別......在我的情況下,我有一個包含我想要發送的數據包的緩衝區。如果我明白了,它不會被視爲與描述符相同,所以它不可能直接傳遞給sendfile();對 ? – Spider

+0

不,'sendfile'只在描述符之間複製。如果源是內存緩衝區,則不能使用它。然後你必須使用'sendto'。 –

回答

0

我不確定sendfile是否適用於UDP套接字,但是,memfd_create從內存創建文件描述符,理論上可以允許繞過從用戶空間到內核的複製。

不過雖然,發送內核時必須將數據先複製到內核套接字緩衝區,因爲它需要使用UDP,IP和以太網頭,不能就地完成前面加上用戶數據。即使使用sendfile也無法避免此複製。

要做到真正的零拷貝聯網,你可能想看看PF_RING ZC (Zero Copy)司機:

點播內核的旁路PF_RING意識到司機

PF_RING™ZC配備了一個新的新一代支持PF_RING™的驅動程序可以在內核或旁路模式下使用。安裝完成後,驅動程序將作爲標準Linux驅動程序運行,您可以在其中執行正常網絡連接(例如ping或SSH)。當使用PF_RING™時,它們比香草驅動程序更快,因爲它們直接與它們相互作用。如果您在零拷貝使用PF_RING-aware驅動打開設備(例如pfcount -i陳竺:eth1的)設備不可用時,因爲它是在零拷貝通過內核旁路訪問,與前任DNA發生了標準的網絡。一旦訪問該設備的應用程序關閉,標準聯網活動可以再次發生。