日本搞逼视频_黄色一级片免费在线观看_色99久久_性明星video另类hd_欧美77_综合在线视频

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > php框架 > 框架設計 > 什么是Zero-Copy?

什么是Zero-Copy?

來源:程序員人生   發布時間:2016-11-21 09:03:52 閱讀次數:4562次

概述

斟酌這樣1種經常使用的情形:你需要將靜態內容(類似圖片、文件)展現給用戶。那末這個情形就意味著你需要先將靜態內容從磁盤中拷貝出來放到1個內存buf中,然后將這個buf通過socket傳輸給用戶,進而用戶或靜態內容的展現。這看起來再正常不過了,但是實際上這是很低效的流程,我們把上面的這類情形抽象成下面的進程:

read(file, tmp_buf, len); write(socket, tmp_buf, len);

首先調用read將靜態內容,這里假定為文件A,讀取到tmp_buf, 然后調用write將tmp_buf寫入到socket中,如圖:

[圖片]
在這個進程中文件A的經歷了4次copy的進程:

  1. 首先,調用read時,文件A拷貝到了kernel模式;
  2. 以后,CPU控制將kernel模式數據copy到user模式下;
  3. 調用write時,先將user模式下的內容copy到kernel模式下的socket的buffer中;
  4. 最后將kernel模式下的socket buffer的數據copy到網卡裝備中傳送;

從上面的進程可以看出,數據白白從kernel模式到user模式走了1圈,浪費了2次copy(第1次,從kernel模式拷貝到user模式;第2次從user模式再拷貝回kernel模式,即上面4次進程的第2和3步驟。)。而且上面的進程中kernel和user模式的上下文的切換也是4次。

榮幸的是,你可以用1種叫做Zero-Copy的技術來去掉這些無謂的copy。利用程序用Zero-Copy來要求kernel直接把disk的data傳輸給socket,而不是通過利用程序傳輸。Zero-Copy大大提高了利用程序的性能,并且減少了kernel和user模式上下文的切換。


詳述

Zero-Copy技術省去了將操作系統的read buffer拷貝到程序的buffer,和從程序buffer拷貝到socket buffer的步驟,直接將read buffer拷貝到socket buffer. Java NIO中的FileChannal.transferTo()方法就是這樣的實現,這個實現是依賴于操作系統底層的sendFile()實現的。

public void transferTo(long position, long count, WritableByteChannel target);

他底層的調用時系統調用sendFile()方法:

#include <sys/socket.h> ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count);

下圖展現了在transferTo()以后的數據流向:
[圖片]

下圖展現了在使用transferTo()以后的上下文切換:
[圖片]

使用了Zero-Copy技術以后,全部進程以下:

  1. transferTo()方法使得文件A的內容直接拷貝到1個read buffer(kernel buffer)中;
  2. 然后數據(kernel buffer)拷貝到socket buffer中。
  3. 最后將socket buffer中的數據拷貝到網卡裝備(protocol engine)中傳輸;
    這明顯是1個偉大的進步:這里把上下文的切換次數從4次減少到2次,同時也把數據copy的次數從4次下降到了3次。

但是這是Zero-Copy么,答案是不是定的。


進階

Linux 2.1內核開始引入了sendfile函數(上1節有提到),用于將文件通過socket傳送。

sendfile(socket, file, len);

該函數通過1次系統調用完成了文件的傳送,減少了原來read/write方式的模式切換。另外更是減少了數據的copy, sendfile的詳細進程如圖:
[圖片]
通過sendfile傳送文件只需要1次系統調用,當調用sendfile時:

  1. 首先(通過DMA)將數據從磁盤讀取到kernel buffer中;
  2. 然后將kernel buffer拷貝到socket buffer中;
  3. 最后將socket buffer中的數據copy到網卡裝備(protocol engine)中發送;

這個進程就是第2節(詳述)中的那個步驟。

sendfiel與read/write模式相比,少了1次copy。但是從上述進程中也能夠發現從kernel buffer中將數據copy到socket buffer是沒有必要的。

Linux2.4 內核對sendfile做了改進,如圖:
[圖片]

改進后的處理進程以下:

  1. 將文件拷貝到kernel buffer中;
  2. 向socket buffer中追加當前要產生的數據在kernel buffer中的位置和偏移量;
  3. 根據socket buffer中的位置和偏移量直接將kernel buffer的數據copy到網卡裝備(protocol engine)中;

經過上述進程,數據只經過了2次copy就從磁盤傳送出去了。
這個才是真實的Zero-Copy(這里的零拷貝是針對kernel來說的,數據在kernel模式下是Zero-Copy)。

正是Linux2.4的內核做了改進,Java中的TransferTo()實現了Zero-Copy,以下圖:
這里寫圖片描述

Zero-Copy技術的使用處景有很多,比如Kafka, 又或是Netty等,可以大大提升程序的性能。


參考資料

  1. Zero-Copy&sendfile淺析
  2. Efficient data transfer through zero copy
  3. Kafka Zero-Copy 使用分析
  4. 理解Netty中的零拷貝(Zero-Copy)機制
生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 午夜视频在线免费 | 97av精品| 亚洲 欧美 视频 | av一区二区三区 | 亚洲一二三区视频 | 亚洲乱码一区二区 | 久久久久久国产精品免费免费 | 国产综合一区二区 | 久久99精品视频 | 三级在线播放 | 野花成人免费视频 | 青青av | 亚洲精品一二区 | aaaa黄色片 | 亚洲一区二区三区四区精品 | 色婷婷亚洲综合 | 日韩午夜视频在线观看 | 不卡一区二区在线 | 精品免费国产一区二区三区四区 | 国产精品一区二区三区四区 | 精品久久久久久久久久久久久久久 | 日韩午夜视频在线观看 | av网站免费看 | 国产精品不卡在线 | 日韩经典一区二区 | 亚洲国产一区在线观看 | 国产午夜精品在线观看 | 成人性生交大片免费观看嘿嘿视频 | 91精品一区二区三区久久久久久 | 欧洲亚洲精品久久久久 | 中文字幕一区二区三区在线播放 | 99视频在线免费观看 | 看免费黄色一级片 | 国产成人一区二区 | 国产精品伦一区二区三级视频 | 亚洲成a| 久久久国产精品一区 | 精品国产一区二区三区麻豆小说 | 国产黄a三级三级三级av在线看 | youjizz亚洲女人 | 日韩精品在线看 |