使用sendfile()優化資料傳輸

2021-10-05 17:32:48 字數 1970 閱讀 4202

支援internet快速發展的開發人員面臨著乙個日益嚴重的問題:如何簡化從伺服器到客戶端的資料傳輸。

sendfile()是為解決該問題而引入的乙個相對較新的作業系統核心原語。

該系統呼叫的原型是:

ssize_t sendfile(int out_fd,int in_fd,off_t * offset,size_t count)

in_fd是開啟供讀取的檔案描述符。

out_fd是為寫入而開啟的描述符。

偏移量是指向儲存輸入檔案指標位置的變數的指標,sendfile()從該位置開始讀取資料。

count是要在檔案描述符之間複製的位元組數。

sendfile()的優勢在於,它提供了對當前linux網路堆疊中擴充套件功能的訪問-「零複製」機制,用於將tcp幀直接從主機記憶體傳輸到網絡卡緩衝區。為了更好地理解零拷貝和sendfile(),讓我們考慮在預傳送檔案時代將檔案傳送到套接字需要做什麼。首先,在使用者空間中分配乙個資料緩衝區。然後,我們必須使用read()syscall將檔案中的資料複製到此緩衝區中。

(通常,此操作將資料從磁碟複製到os快取,然後再次將其從快取複製到使用者空間,執行所謂的「上下文切換」。)之後,我們應該使用write()syscall來傳送內容。

網路緩衝區:int out_fd,int in_fd;

字元緩衝區[buflen];

…/ *為清楚起見,跳過了非實質性*** /

…read(in_fd,buffer,buflen); / * syscall,進行上下文切換* /

write(out_fd,buffer,buflen); / * syscall,進行上下文切換* /

os核心必須將所有資料至少複製兩次:從核心空間複製到使用者空間,然後再複製回去。每個操作都需要乙個上下文切換過程,其中涉及許多複雜且占用大量cpu的操作。系統實用程式vmstat可用於顯示大多數類似unix的作業系統上的當前上下文切換速率。檢視稱為「 cs」的列,了解在取樣期間發生的許多上下文切換。嘗試不同的載荷型別,以檢視它們對該引數造成的影響。

詳細說明切換過程:

讓我們更深入地研究切換上下文的過程,以更好地了解相關費用。從使用者空間呼叫系統的過程中涉及許多操作。例如,必須將虛擬記憶體頁面從使用者空間一次切換到核心,然後再切換回核心。此過程需要執行相對昂貴的(就cpu週期而言)指令,並與稱為全域性描述符表(gdt)和本地描述符表(ldt)的記憶體頁控制表一起使用。還需要注意另一種稱為tss(任務狀態段)的結構。 而且,存在一些隱式且非常昂貴的操作,這些操作不是直接由上下文切換過程引起的。我們可以在支援虛擬記憶體所需的虛擬實體地址轉換操作的示例中對此進行說明。轉換所需的資料(頁表)也儲存在記憶體中,因此,除了訪問以下內容外,每個cpu對記憶體位置的請求都將需要對主儲存器進行一次或多次訪問(以讀取轉換表條目)。獲取請求的資料。現代cpu通常包括轉換後備緩衝區(通常縮寫為tlb)。tlb用作頁表條目的快取,儲存最近訪問的條目。(這是乙個簡化的解釋。)tlb快取記憶體未命中具有巨大的潛在成本-幾次記憶體訪問和頁面錯誤處理程式的執行。

使用sendfile()零複製方法,如果可能的話,使用直接記憶體訪問(dma)硬體將資料立即從磁碟讀取到os快取中。tlb快取保持不變。利用sendfile()原語的應用程式的效能很高,因為該系統呼叫不直接指向記憶體,因此可以最大程度地降低效能開銷。通常,要直接從系統緩衝區中獲取要傳輸的資料,而無需上下文切換,也不會破壞快取。因此,在伺服器應用程式中使用sendfile()可以大大減少cpu負載。在我們的示例中,用mmap()替換read()不會有太大變化。但是,mmap syscall要求將檔案描述符指定的檔案(或其他物件)中的某些位元組對映到虛擬記憶體中。嘗試從該記憶體中讀取資料將導致磁碟操作。通過此呼叫,我們可以消除讀取操作,因為系統會將對映的記憶體直接寫入套接字,而無需顯式呼叫read()且無需分配緩衝區。但是,此操作的確會導致tlb快取重新整理,因此每位元組傳輸的cpu負載會更高。

參考部落格:use sendfile() to optimize data transfer

sendfile優化檔案拷貝

現在流行的 web 伺服器裡面都提供 sendfile 選項用來提高伺服器效能,那到底 sendfile 是什麼,怎麼影響效能的呢?sendfile 實際上是 linux 2.0 以後的推出的乙個系統呼叫,web 伺服器可以通過調整自身的配置來決定是否利用 sendfile 這個系統呼叫。先來看一下...

sendfile優化檔案拷貝

現在流行的 web 伺服器裡面都提供 sendfile 選項用來提高伺服器效能,那到底 sendfile 是什麼,怎麼影響效能的呢?sendfile 實際上是 linux 2.0 以後的推出的乙個系統呼叫,web 伺服器可以通過調整自身的配置來決定是否利用 sendfile 這個系統呼叫。先來看一下...

sendfile優化檔案拷貝

現在流行的 web 伺服器裡面都提供 sendfile 選項用來提高伺服器效能,那到底 sendfile 是什麼,怎麼影響效能的呢?sendfile 實際上是 linux 2.0 以後的推出的乙個系統呼叫,web 伺服器可以通過調整自身的配置來決定是否利用 sendfile 這個系統呼叫。先來看一下...