新聞中心
數(shù)據(jù)搬運(yùn)工
Hi,我是CPU一號(hào)車間的阿Q,有段日子沒(méi)見(jiàn)面了。

還記得上回說(shuō)到咱們廠里用上了DMA技術(shù)(太慢不能忍!CPU又拿硬盤和網(wǎng)卡開刀了!)之后,我們總算解放了,再也不用奔波于網(wǎng)卡、硬盤與內(nèi)存之間搬運(yùn)數(shù)據(jù)了。
前段時(shí)間,我到二號(hào)車間虎子那里去串門,發(fā)現(xiàn)他正忙的滿頭大汗。
“老哥,你這是接到什么任務(wù)了?看把你給你忙的”
虎子一看我過(guò)來(lái),擦了擦頭上的汗說(shuō)到:“我這是在搬運(yùn)數(shù)據(jù)啊,剛剛搬完一批,累死我了”
我有些疑惑:“咱們現(xiàn)在不是有DMA技術(shù)了嗎,找外包DMA控制器搬運(yùn)啊,你干嘛還親自上陣?”
“DMA是用于I/O外部設(shè)備與內(nèi)存之間搬運(yùn)數(shù)據(jù),我現(xiàn)在的任務(wù)是內(nèi)存之間的復(fù)制拷貝工作,這DMAC也幫不上什么忙啊,還不得我親自動(dòng)手復(fù)制?!?/p>
我癟了癟嘴,“也是,但愿我不要接到這種任務(wù)”
“先不跟你聊了,又有活要干了”,虎子屁股還沒(méi)坐熱,又起身去忙了,我也起身準(zhǔn)備回去。
“我靠!怎么又要拷貝這批數(shù)據(jù)!”,我剛走兩步,就聽(tīng)到虎子的吐槽。
我回過(guò)頭去問(wèn)到:“咋了這是?”
“我剛才才把這份數(shù)據(jù)從內(nèi)核地址空間往用戶態(tài)地址空間拷貝了一次,這還沒(méi)喘口氣,又讓我再搬一次從用戶態(tài)再搬回內(nèi)核地址空間,太折騰我了吧!”
我拍了拍他的肩膀說(shuō)到:“嗨,這沒(méi)辦法,咱們就是打工的,哪輪得到咱們挑挑揀揀啊,加油吧!”
我一邊給他打氣,一邊暗自祈禱別給我安排這種活,又累有沒(méi)有技術(shù)含量。
天有不測(cè)風(fēng)云,回到一號(hào)車間沒(méi)多久,我也攤上這種事了。老話說(shuō)得好,真是怕什么來(lái)什么。
一開始我還能忍著,時(shí)間一久我就抑制不住心里的不滿了,還真是落在自己身上才知道痛。
數(shù)據(jù)的四次拷貝
第二天,我約上虎子去找操作系統(tǒng)內(nèi)存管理部門反應(yīng)這事。
內(nèi)存管理部門居然踢皮球,說(shuō)這事不歸他們管,讓我們找I/O部門,沒(méi)辦法,我們又來(lái)到I/O部門反應(yīng)這事。
I/O部門的人聽(tīng)完我們的抱怨,也很無(wú)奈:“兩位,實(shí)在不是我們故意戲耍你們。之前讓你們兩次搬運(yùn)數(shù)據(jù)實(shí)在沒(méi)有辦法,這是上邊的應(yīng)用程序要這樣寫的。他們要把硬盤上的文件讀取出來(lái),然后再通過(guò)網(wǎng)卡發(fā)送出去。這一讀一寫的不就要搬兩次嗎?”
- File.read(file, buf, len);
- Socket.send(socket, buf, len);
“硬盤?網(wǎng)卡?這,這,這我們不是有了DMA技術(shù)了嗎,正好解決了和他們的數(shù)據(jù)傳輸,干嘛還另外讓我們?cè)僭趦?nèi)存之間復(fù)制來(lái)復(fù)制去呢?”,我問(wèn)到。
對(duì)方看出了我們的疑惑,在旁邊的白板上畫了一張圖:
“你們看,數(shù)據(jù)從硬盤最終到網(wǎng)卡,因?yàn)橛袘?yīng)用程序的參與,他們需要先讀到他們?cè)谟脩艨臻g的緩存區(qū),再發(fā)送出去,這樣就總共有四次數(shù)據(jù)的傳輸。其中從硬盤到內(nèi)核空間和從內(nèi)核空間到網(wǎng)卡這兩個(gè)環(huán)節(jié),DMAC可以幫你們搬運(yùn)。不過(guò)剩下兩次的用戶空間和內(nèi)核空間的來(lái)回拷貝,這還得靠你們來(lái)搬運(yùn)下啊”
“原來(lái)是這樣,唉,看來(lái)是沒(méi)辦法避免了,咱先回去吧”,虎子看完圖垂頭喪氣的說(shuō)到。
我卻不愿放棄,想在這圖中找出可以優(yōu)化改進(jìn)的地方。
“能不能讓數(shù)據(jù)不要去應(yīng)用程序那里,直接在內(nèi)核空間復(fù)制一次就好,我們就可以少搬運(yùn)一次了?”,我拋出了一個(gè)問(wèn)題。
“那怎么可能呢,他不讀上去,后面怎么發(fā)出去呢?不行不行”,I/O部門的人連連搖頭。
“還是可以發(fā)啊,你看像這樣···反正最后也是把數(shù)據(jù)從內(nèi)核空間交給網(wǎng)卡發(fā),只是免去了數(shù)據(jù)去用戶空間白晃一圈的浪費(fèi)”,我把他畫的圖改了一下,不肯放棄解釋到。
對(duì)方被我的話點(diǎn)醒了一般,眼珠左右轉(zhuǎn)動(dòng),反復(fù)思考。
片刻之后,回到:“還是不行,萬(wàn)一人家要對(duì)讀取的文件數(shù)據(jù)進(jìn)行修改,或者解密,那還是得讀到他的用戶空間緩存區(qū)才行”
我想了一下,這似乎沒(méi)辦法避免,說(shuō)到:“那這種情況咱們就認(rèn)了,反正以我的經(jīng)驗(yàn)來(lái)看,你說(shuō)的這種情況不多。大部分情況下都是數(shù)據(jù)原封不動(dòng)的從內(nèi)核到用戶空間,又從用戶空間回到內(nèi)核?!?/p>
I/O部門的人再也沒(méi)有什么說(shuō)辭,點(diǎn)了點(diǎn)頭答應(yīng)了下來(lái),說(shuō)把我們的意見(jiàn)匯報(bào)到Linux帝國(guó)高層討論后才能做決定。我們就先回去等消息了。
零拷貝技術(shù)
不過(guò)后來(lái)工作太忙,遲遲沒(méi)有操作系統(tǒng)那邊的消息,慢慢的我們就把這事給淡忘了,直到前幾天······
“阿Q,聽(tīng)說(shuō)了嗎,最近Linux帝國(guó)新成立了一個(gè)公司,居然繞過(guò)我們CPU就能把數(shù)據(jù)從網(wǎng)卡寫入硬盤中”,虎子火急火燎的來(lái)找我。
“不可能啊,按照我們之前的方案,怎么說(shuō)也得至少經(jīng)過(guò)我們拷貝一次吧”
“根本不用,他們號(hào)稱是零拷貝技術(shù)”
我們趕緊放下手里的工作,去打聽(tīng)下究竟怎么回事。
原來(lái),Linux帝國(guó)最近新推出了一個(gè)API,叫sendfile
- ssize_t sendfile(
- int out_fd,
- int in_fd,
- off_t *offset,
- size_t count
- );
只需要指定打開文件的描述符和要發(fā)送的網(wǎng)絡(luò)接口描述符,就直接實(shí)現(xiàn)了把文件通過(guò)網(wǎng)絡(luò)發(fā)出去。
我們?cè)俅蝸?lái)到了操作系統(tǒng)I/O部門,對(duì)方一看是我們,熱情的接待了我們。
“你們來(lái)的正好,我還沒(méi)來(lái)得及告訴你們呢。上次你們提的思路非常好,帝國(guó)高層非常重視,我一反應(yīng)上去,當(dāng)即就采納了你們的意見(jiàn)。這不你們估計(jì)也知道了,推出了新的API給應(yīng)用程序們使用,省去了數(shù)據(jù)白白去用戶空間轉(zhuǎn)一圈的開銷。一推出就大受歡迎,說(shuō)起來(lái)還得感謝你們呢”
“原來(lái)是這樣,我說(shuō)最近怎么搬運(yùn)數(shù)據(jù)的工作少了不少。不過(guò)你們是怎么做到零拷貝的?”
I/O部門的人瞅了我們幾眼,得意的一笑,“帝國(guó)高層在討論你們的方案時(shí),覺(jué)得還可以再進(jìn)一步優(yōu)化,直接把從硬盤讀取到的數(shù)據(jù)緩沖區(qū)地址和長(zhǎng)度給到網(wǎng)絡(luò)socket描述符,就不用你們?cè)侔徇\(yùn)一次數(shù)據(jù),徹底解放你們,所以叫零拷貝啦!”
我倆連連點(diǎn)頭稱贊。
“還沒(méi)完呢!咱Linux帝國(guó)還把這一技術(shù)推廣到了文件數(shù)據(jù)復(fù)制上,增加了另一個(gè)API:splice,以后文件拷貝也可以減輕你們的負(fù)擔(dān)了”
- ssize_t splice(
- int fd_in,
- loff_t *off_in,
- int fd_out,
- loff_t *off_out,
- size_t len,
- unsigned int flags
- );
我倆回去之后,把這一消息告知了全廠,大家都高興壞了,原來(lái)各個(gè)車間都受苦久矣。
本文標(biāo)題:CPU:別再拿我當(dāng)搬磚工!一個(gè)故事看懂零拷貝技術(shù)
文章分享:http://www.5511xx.com/article/dpepjcc.html


咨詢
建站咨詢
