日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

傳統(tǒng)IO過程

考慮這樣一個過程:我們從磁盤中讀取一個文件數(shù)據(jù),然后將數(shù)據(jù)通過網(wǎng)絡(luò)傳輸?shù)搅硪粋€機(jī)器。對用戶來說可能就是簡單的理解為兩步操作。

File.read(fileDesc, buf, len);

Socket.send(socket, buf, len);

但是,如果我們看傳輸中涉及的內(nèi)核部分的內(nèi)部工作原理,我們將看到

即使是使用DMA傳輸?shù)挠布С郑@種方法也效率很低。首先,內(nèi)核將使用DMA將磁盤中的數(shù)據(jù)加載到其自己的內(nèi)核緩沖區(qū)中,除非在先前訪問同一文件之后,該數(shù)據(jù)仍被緩存在內(nèi)核緩沖區(qū)中。

這樣傳輸不需要太多的CPU工作,CPU只需要進(jìn)行緩沖區(qū)管理和DMA創(chuàng)建和處理。linux 操作系統(tǒng)會根據(jù) read() 系統(tǒng)調(diào)用指定的應(yīng)用程序地址空間的地址,把這塊數(shù)據(jù)存放到請求這塊數(shù)據(jù)的應(yīng)用程序的地址空間中去,在接下來的處理過程中,操作系統(tǒng)需要將數(shù)據(jù)再一次從用戶應(yīng)用程序地址空間的緩沖區(qū)拷貝到與網(wǎng)絡(luò)堆棧相關(guān)的內(nèi)核緩沖區(qū)中去,這個過程也是需要占用 CPU 的。

數(shù)據(jù)拷貝操作結(jié)束以后,數(shù)據(jù)會被打包,然后發(fā)送到網(wǎng)絡(luò)接口卡上去。在數(shù)據(jù)傳輸?shù)倪^程中,應(yīng)用程序可以先返回進(jìn)而執(zhí)行其他的操作。

之后,在調(diào)用 write() 系統(tǒng)調(diào)用的時候,用戶應(yīng)用程序緩沖區(qū)中的數(shù)據(jù)內(nèi)容可以被安全的丟棄或者更改,因?yàn)椴僮飨到y(tǒng)已經(jīng)在內(nèi)核緩沖區(qū)中保留了一份數(shù)據(jù)拷貝,當(dāng)數(shù)據(jù)被成功傳送到硬件上之后,這份數(shù)據(jù)拷貝就可以被丟棄。

所以我們會發(fā)現(xiàn)這個過程涉及到了3次上下文切換,和4次數(shù)據(jù)拷貝的過程:

程序員必知必會的零拷貝技術(shù)

 

利用mmap()

在 Linux 中,減少拷貝次數(shù)的一種方法是調(diào)用 mmap() 來代替調(diào)用 read,比如:

tmp_buf = mmap(file, len);

write(socket, tmp_buf, len);

首先,應(yīng)用程序調(diào)用了 mmap() 之后,數(shù)據(jù)會先通過 DMA 拷貝到操作系統(tǒng)內(nèi)核的緩沖區(qū)中去。接著,應(yīng)用程序跟操作系統(tǒng)共享這個緩沖區(qū),這樣,操作系統(tǒng)內(nèi)核和應(yīng)用程序存儲空間就不需要再進(jìn)行任何的數(shù)據(jù)拷貝操作。應(yīng)用程序調(diào)用了 write() 之后,操作系統(tǒng)內(nèi)核將數(shù)據(jù)從原來的內(nèi)核緩沖區(qū)中拷貝到與 socket 相關(guān)的內(nèi)核緩沖區(qū)中。接下來,數(shù)據(jù)從內(nèi)核 socket 緩沖區(qū)拷貝到協(xié)議引擎中去,這是第三次數(shù)據(jù)拷貝操作

程序員必知必會的零拷貝技術(shù)

 

盡管mmap()可以減少一次 I/O 拷貝,但由于mmap()的實(shí)現(xiàn)很復(fù)雜,調(diào)用mmap()將會帶來額外的開銷,因此在一些情況下,沒有使用mmap()的必要:

訪問小文件時,直接使用read()或write()將更加高效。

單個進(jìn)程對文件執(zhí)行順序訪問時(sequential access),使用mmap()幾乎不會帶來性能上的提升。譬如說,使用read()順序讀取文件時,文件系統(tǒng)會使用 read-ahead 的方式提前將文件內(nèi)容緩存到文件系統(tǒng)的緩沖區(qū),因此使用read()將很大程度上可以命中緩存。

那么,在什么情況下使用mmap()去訪問文件會更高效呢?

對文件執(zhí)行隨機(jī)訪問時,如果使用read()或write(),則意味著較低的 cache 命中率。這種情況下使用mmap()通常將更高效。

多個進(jìn)程同時訪問同一個文件時(無論是順序訪問還是隨機(jī)訪問),如果使用mmap(),那么 OS 緩沖區(qū)的文件內(nèi)容可以在多個進(jìn)程之間共享,從操作系統(tǒng)角度來看,使用mmap()可以大大節(jié)省內(nèi)存。

程序員必知必會的零拷貝技術(shù)

 

sendfile()

為了簡化用戶接口,同時還要繼續(xù)保留 mmap()/write() 技術(shù)的優(yōu)點(diǎn):減少 CPU 的拷貝次數(shù),Linux 在版本 2.1 中引入了 sendfile() 這個系統(tǒng)調(diào)用。

sendfile(sockfd, fd, NULL, len);

sendfile() 不僅減少了數(shù)據(jù)拷貝操作,它也減少了上下文切換。首先:sendfile() 系統(tǒng)調(diào)用利用 DMA 引擎將文件中的數(shù)據(jù)拷貝到操作系統(tǒng)內(nèi)核緩沖區(qū)中,然后數(shù)據(jù)被拷貝到與 socket 相關(guān)的內(nèi)核緩沖區(qū)中去。接下來,DMA 引擎將數(shù)據(jù)從內(nèi)核 socket 緩沖區(qū)中拷貝到協(xié)議引擎中去。

程序員必知必會的零拷貝技術(shù)

 

可以看到,與使用read()和write()發(fā)送文件相比,使用sendfile()減少了一次 I/O 拷貝和兩次 上下文切換。

sendfile with DMA Gather Copy

為了避免操作系統(tǒng)內(nèi)核造成的數(shù)據(jù)副本,需要用到一個支持收集操作的網(wǎng)絡(luò)接口,這也就是說,待傳輸?shù)臄?shù)據(jù)可以分散在存儲的不同位置上,而不需要在連續(xù)存儲中存放。

這樣一來,從文件中讀出的數(shù)據(jù)就根本不需要被拷貝到 socket 緩沖區(qū)中去,而只是需要將緩沖區(qū)描述符傳到網(wǎng)絡(luò)協(xié)議棧中去,之后其在緩沖區(qū)中建立起數(shù)據(jù)包的相關(guān)結(jié)構(gòu),然后通過 DMA 收集拷貝功能將所有的數(shù)據(jù)結(jié)合成一個網(wǎng)絡(luò)數(shù)據(jù)包。

程序員必知必會的零拷貝技術(shù)

 

網(wǎng)卡的 DMA 引擎會在一次操作中從多個位置讀取包頭和數(shù)據(jù)。Linux 2.4 版本中的 socket 緩沖區(qū)就可以滿足這種條件,這也就是用于 Linux 中的眾所周知的零拷貝技術(shù),這種方法不但減少了因?yàn)槎啻紊舷挛那袚Q所帶來開銷,同時也減少了處理器造成的數(shù)據(jù)副本的個數(shù)。

對于用戶應(yīng)用程序來說,代碼沒有任何改變。首先,sendfile() 系統(tǒng)調(diào)用利用 DMA 引擎將文件內(nèi)容拷貝到內(nèi)核緩沖區(qū)去;然后,將帶有文件位置和長度信息的緩沖區(qū)描述符添加到 socket 緩沖區(qū)中去,此過程不需要將數(shù)據(jù)從操作系統(tǒng)內(nèi)核緩沖區(qū)拷貝到 socket 緩沖區(qū)中,DMA 引擎會將數(shù)據(jù)直接從內(nèi)核緩沖區(qū)拷貝到協(xié)議引擎中去,這樣就避免了最后一次數(shù)據(jù)拷貝。

程序員必知必會的零拷貝技術(shù)

 

分享到:
標(biāo)簽:拷貝
用戶無頭像

網(wǎng)友整理

注冊時間:

網(wǎng)站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學(xué)四六

運(yùn)動步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績評定2018-06-03

通用課目體育訓(xùn)練成績評定