Zero-Copysendfile浅析
Zero-Copy&sendfile淺析
標(biāo)簽: buffersocket磁盤linuxlighttpdweb服務(wù) 2011-01-17 11:53 2923人閱讀 評論(0) 收藏 舉報 分類: 高性能服務(wù)器版權(quán)聲明:本文為博主原創(chuàng)文章,未經(jīng)博主允許不得轉(zhuǎn)載。
一、典型IO調(diào)用的問題
一個典型的web服務(wù)器傳送靜態(tài)文件(如CSS,JS,圖片等)的過程如下:
read(file, tmp_buf, len);
write(socket, tmp_buf, len);
首先調(diào)用read將文件從磁盤讀取到tmp_buf,然后調(diào)用write將tmp_buf寫入到socket,在這過程中會出現(xiàn)四次數(shù)據(jù) copy,過程如圖1所示
圖1
?
1。當(dāng)調(diào)用read系統(tǒng)調(diào)用時,通過DMA(Direct Memory Access)將數(shù)據(jù)copy到內(nèi)核模式
2。然后由CPU控制將內(nèi)核模式數(shù)據(jù)copy到用戶模式下的 buffer中
3。read調(diào)用完成后,write調(diào)用首先將用戶模式下 buffer中的數(shù)據(jù)copy到內(nèi)核模式下的socket buffer中
4。最后通過DMA copy將內(nèi)核模式下的socket buffer中的數(shù)據(jù)copy到網(wǎng)卡設(shè)備中傳送。
從上面的過程可以看出,數(shù)據(jù)白白從內(nèi)核模式到用戶模式走了一 圈,浪費了兩次copy,而這兩次copy都是CPU copy,即占用CPU資源。
?
二、Zero-Copy&Sendfile()
Linux 2.1版本內(nèi)核引入了sendfile函數(shù),用于將文件通過socket傳送。
sendfile(socket, file, len);
該函數(shù)通過一次系統(tǒng)調(diào)用完成了文件的傳送,減少了原來 read/write方式的模式切換。此外更是減少了數(shù)據(jù)的copy,sendfile的詳細(xì)過程圖2所示:
圖2
通過sendfile傳送文件只需要一次系統(tǒng)調(diào)用,當(dāng)調(diào)用 sendfile時:
1。首先通過DMA copy將數(shù)據(jù)從磁盤讀取到kernel buffer中
2。然后通過CPU copy將數(shù)據(jù)從kernel buffer copy到sokcet buffer中
3。最終通過DMA copy將socket buffer中數(shù)據(jù)copy到網(wǎng)卡buffer中發(fā)送
sendfile與read/write方式相比,少了 一次模式切換一次CPU copy。但是從上述過程中也可以發(fā)現(xiàn)從kernel buffer中將數(shù)據(jù)copy到socket buffer是沒必要的。
為此,Linux2.4內(nèi)核對sendfile做了改進(jìn),如圖3所示
圖3
改進(jìn)后的處理過程如下:
1。DMA copy將磁盤數(shù)據(jù)copy到kernel buffer中
2。向socket buffer中追加當(dāng)前要發(fā)送的數(shù)據(jù)在kernel buffer中的位置和偏移量
3。DMA gather copy根據(jù)socket buffer中的位置和偏移量直接將kernel buffer中的數(shù)據(jù)copy到網(wǎng)卡上。
經(jīng)過上述過程,數(shù)據(jù)只經(jīng)過了2次copy就從磁盤傳送出去了。
(可能有人要糾結(jié)“不是說Zero-Copy么?怎么還有兩次copy啊”,事實上這個Zero copy是針對內(nèi)核來講的,數(shù)據(jù)在內(nèi)核模式下是Zero-copy的。話說回來,文件本身在瓷盤上要真是完全Zero-copy就能傳送,那才見鬼了 呢)。
當(dāng)前許多高性能http server都引入了sendfile機制,如nginx,lighttpd等。
三、Java NIO中的transferTo()
Java NIO中
FileChannel.transferTo(long position, long count, WriteableByteChannel target)
方法將當(dāng)前通道中的數(shù)據(jù)傳送到目標(biāo)通道target中,在支持Zero-Copy的linux系統(tǒng)中,transferTo()的實現(xiàn)依賴于 sendfile()調(diào)用。
?
四、參考文檔
《Zero Copy I: User-Mode Perspective》http://www.linuxjournal.com/article/6345?page=0,0
《Efficient data transfer through zero copy》http://www.ibm.com/developerworks/linux/library/j-zerocopy
《The C10K problem》http://www.kegel.com/c10k.html
總結(jié)
以上是生活随笔為你收集整理的Zero-Copysendfile浅析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Adobe illustrator 排版
- 下一篇: GPU(CUDA)学习日记(九)----