什麼是Zero-Copy?
想要了解這個名詞是指什麼意思的話,
read(file, tmp_buf, len);
write(socket, tmp_buf, len);
Figure 1的圖說明了,這兩行程式實際的運作流程。
(1)
(2)執行write後,Kernel的syscall write(),再用CPU去把user buffer的資料搬到socket buffer裏,資料進到socket buffer後,
問題分析:
從整個流程你應該會發現有一堆資料是重覆的,
以硬體的角度來看,其實是可以做到直接跳過記憶體的資料暫存的,
那我們是否可以減少user buffer這個部份呢?答案是肯定的,
簡化範例程式如下:
tmp_buf = mmap(file, len);
write(socket, tmp_buf, len);
Figure 2的圖說明了,這兩行程式實際的運作流程。
(1)
(2)write()執行,把kernel buffer經由CPU複製到socket buffer,然後再經由DMA複製到client去。
問題分析:
但是使用mmap來改善並不是不需要付出代價的,
當然一支網路程式不應該這麼做處理的,
(1)方法一:在SIGBUS訊號設置callback function,
(2)方法二:使用租約(lease)的方式(
如:
更好的做法是使用sendfile函式
簡化範例程式如下:
sendfile(socket, file, len);
(1)sendfile執行後,
(2)再把socket buffer的資料經由DMA傳給client去,
問題分析:
所以到目前為止我們已看到改善了不少地方了,
這種方式不僅僅是減少了context switch而且也減少了buffer的使用,
sendfile(socket, file, len);
(1)sendfile執行後,
(2)資料傳給client去也是用DMA的方式,
所以就完成了,不需要CPU去搬資料,
原本資料來源:
http://www.linuxjournal.com/
測試文章:有人針對這篇文章去進行測試的實驗結果
雖然它測起來的傳輸速度似乎沒差,
http://bbs.lpi-china.org/
- Nov 02 Mon 2009 06:03
什麼是Zero-Copy?
close
簡化範例程式如下:
if(fcntl(fd, F_SETSIG, RT_SIGNAL_LEASE) == -1) {
perror("kernel lease set signal");
return -1;
}
/* l_type can be F_RDLCK F_WRLCK */
if(fcntl(fd, F_SETLEASE, l_type)){
perror("kernel lease set type");
return -1;
}
Figure 3的圖說明了,這行程式在Kernel 2.1版本的實際運作流程, sendfile直接取代了read/write兩個函式, 並且減少了context switch的次數。
Figure 4的圖說明了,這行程式在Kernel 2.4版本的實際運作流程
但還有個問題,網路傳輸不見得只有直接傳檔案啊, 如果是傳非檔案的資料,sendfile還是適用嗎? viewthread.php?tid=4292&extra= page%3D1
全站熱搜
留言列表
禁止留言