精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

為什么 P8 程序員的代碼你寫不出來?零拷貝了解一下

開發 項目管理
當前流行的互聯網應用更多的屬于IO密集型,傳統的IO標準接口都是基于數據拷貝的,這篇文章我們主要關注該怎樣從數據拷貝的角度來優化IO性能,讓你的程序在IO性能方面趕超P8。

[[423674]]

計算機處理的任務大體可以分為兩類:CPU密集型與IO密集型。

當前流行的互聯網應用更多的屬于IO密集型,傳統的IO標準接口都是基于數據拷貝的,這篇文章我們主要關注該怎樣從數據拷貝的角度來優化IO性能,讓你的程序在IO性能方面趕超P8。

為什么IO接口要基于數據拷貝?

為了讓廣大碼農們更好的沉迷于自己的一畝三分地,防止ta們分心去關心計算機中的硬件資源分配問題,操作系統誕生了。

操作系統本質上就是一個管家,目的就是更加公平合理的給各個進程分配硬件資源,在操作系統出現之前,程序員需要直面各類硬件,就像這樣:

在這一時期程序員真可謂掌控全局,掌控全局帶來的后果就是你需要掌控所有細節,這顯然不利于生產力的釋放。

操作系統應用而生。

計算機系統就變成這樣了:

現在應用程序不需要和硬件直接交互了,僅從IO的角度上看,操作系統變成了一個類似路由器的角色,把應用程序遞交過來的數據分發到具體的硬件上去,或者從硬件接收數據并分發給相應的進程。

數據傳遞是通過什么呢?就是我們常說的buffer,所謂buffer就是一塊可用的內存空間,用來暫存數據。

操作系統這一中間商導致的問題就是:你需要首先把東西交給操作系統,操作系統再轉手交給硬件,這就必然涉及到數據拷貝。

這就是為什么傳統的IO操作必然需要進行數據拷貝的原因所在。關于操作系統系統完整的闡述請參見博主的《深入理解操作系統》。

然而數據拷貝是有性能損耗的,接下來我們用一個實例來讓大家對該問題有一個更直觀的認知。

網絡服務器

瀏覽器打開一個網頁需要很多數據,包括看到的圖片、html文件、css文件、js文件等等,當瀏覽器請求這類文件時服務器端的工作其實是非常簡單的:服務器只需要從磁盤中抓出該文件然后丟給網絡發送出去。

代碼基本上類似這樣:

  1. read(fileDesc, buf, len); 
  2.  
  3. write(socket, buf, len); 

這兩段代碼非常簡單,第一行代碼從文件中讀取數據存放在buf中,然后將buf中的數據通過網絡發送出去。

注意觀察buf,服務器全程沒有對buf中的數據進行任何修改,buf里的數據在用戶態逛了一圈后揮一揮衣袖沒有帶走半點云彩就回到了內核態。

這兩行看似簡單的代碼實際上在底層發生了什么呢?

答案是這樣的:

在程序看來簡單的兩行代碼在底層是比較復雜的,看到這張圖你應該真心感激操作系統,操作系統就像一個無比稱職的管家,替你把所有臟活累活都承擔下來,好讓你悠閑的在用戶態指點江山。

這簡單的兩行代碼涉及:四次數據拷貝以及四次上下文切換:

read函數會涉及一次用戶態到內核態的切換,操作系統會向磁盤發起一次IO請求,當數據準備好后通過DMA技術把數據拷貝到內核的buffer中,注意本次數據拷貝無需CPU參與。

此后操作系統開始把這塊數據從內核拷貝到用戶態的buffer中,此時read()函數返回,并從內核態切換回用戶態,到這時read(fileDesc, buf, len);這行代碼就返回了,buf中裝好了新鮮出爐的數據。

接下來send函數再次導致用戶態與內核態的切換,此時數據需要從用戶態buf拷貝到網絡協議子系統的buf中,具體點該buf屬于在代碼中使用的這個socket。

此后send函數返回,再次由內核態返回到用戶態;此時在程序員看來數據已經成功發出去了,但實際上數據可能依然停留在內核中,此后第四次數據copy開始,利用DMA技術把數據從socket buf拷貝給網卡,然后真正的發送出去。

這就是看似簡單的這兩行代碼在底層的完整過程。

你覺得這個過程有什么問題嗎?

發現問題

有的同學肯定已經注意到了,既然在用戶態沒有對數據進行任何修改,那為什么要這么麻煩的讓數據在用戶態來個一日游呢?直接在內核態從磁盤給到網卡不就可以了嗎?

恭喜你,答對了!

這種優化思路就是所謂的零拷貝技術,Zero Copy。

總體上來看,優化數據拷貝會有以下三個方向:

用戶態不需要真正的去訪問數據,就像上面這個示例,用戶態根本不需要知道buf里面裝的是什么。在這種情況下無需把數據從內核態拷貝到用戶態然后再把數據從用戶態拷貝回內核態。

數據無需用戶態感知,數據拷貝完全發生在內核態。

內核態不要真正的去訪問數據,用戶態程序可以繞過內核直接和硬件交互,這樣就避免了內核的參與,從而減少數據拷貝的可能。

內核無需感知數據。

如果內核態和用戶態不得不進行數據交互,則優化用戶態與內核態數據的交互方式。

知道了解決問題的思路,我們來看下為了實現零拷貝,計算機系統中都有哪些巧妙的設計。

mmap

是的,就是mmap,在《mmap可以讓程序員實現哪些騷操作》一文中我們對其進行了詳細講解,你能想到mmap還可以實現零拷貝嗎?

對于本文提到的網絡服務器我們可以這樣修改代碼:

  1. buf = mmap(file, len); 
  2.  
  3. write(socket, buf, len); 

你可能會想僅僅將read替換為mmap會有什么優化嗎?

如果你真的理解了mmap就會知道,mmap僅僅將文件內容映射到了進程地址空間中,并沒有真正的拷貝到進程地址空間,這節省了一次從內核態到用戶態的數據拷貝。

同樣的,當調用write時數據直接從內核buf拷貝給了socket buf,而不是像read/write方法中把用戶態數據拷貝給socket buf。

我們可以看到,利用mmap我們節省了一次數據拷貝,上下文切換依然是四次。

盡管mmap可以節省數據拷貝,但維護文件與地址空間的映射關系也是有代價的,除非CPU拷貝數據的時間超過維系映射關系的代價,否則基于mmap的程序性能可能不及傳統的read/write。

此外,如果映射的文件被其它進程截斷,在Linux系統下你的進程將立即接收到SIGBUS信號,因此這種異常情況也需要正確處理。

除了mmap之外,還有其它辦法也可以實現零拷貝。

sendfile

你沒有看錯,在Linux系統下為了解決數據拷貝問題專門設計了這一系統調用:

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

Windows下也有一個作用類似的API:TransmitFile。

這一系統調用的目的是在兩個文件描述之間拷貝數據,但值得注意的是,數據拷貝的過程完全是在內核態完成,因此在網絡服務器的這個例子中我們將把那兩行代碼簡化為一行,也就是調用這里的sendfile。

使用sendfile將節省兩次數據拷貝,因為數據無需傳輸到用戶態:

調用sendfile后,首先DMA機制會把數據從磁盤拷貝到內核buf中,接下來把數據從內核buf拷貝到相應的socket buf中,最后利用DMA機制將數據從socket buf拷貝到網卡中。

我們可以看到,同使用傳統的read/write相比少了一次數據拷貝,而且內核態和用戶態的切換只有兩次。

有的同學可能已經看出了,這好像不是零拷貝吧,在內核中這不是還有一次從內核態buf到socket buf的數據拷貝嗎?這次拷貝看上去也是沒有必要的。

的確如此,為解決這一問題,單純的軟件機制已經不夠用了,我們需要硬件來幫一點忙,這就是DMA Gather Copy。

sendfile 與DMA Gather Copy

傳統的DMA機制必須從一段連續的空間中傳輸數據,就像這樣:

很顯然,你需要在源頭上把所有需要的數據都拷貝到一段連續的空間中:

現在肯定有同學會問,為什么不直接讓DMA可以從多個源頭收集數據呢?

這就是所謂的DMA Gather Copy。

有了這一特性,無需再將內核文件buf中的數據拷貝到socket buf,而是網卡利用DMA Gather Copy機制將消息頭以及需要傳輸的數據等直接組裝在一起發送出去。

在這一機制的加持下,CPU甚至完全不需要接觸到需要傳輸的數據,而且程序利用sendfile編寫的代碼也無需任何改動,這進一步提升了程序性能。

當前流行的消息中間件kafka就基于sendfile來高效傳輸文件。

其實你應該已經看出來了,高效IO的秘訣其實很簡單:盡量少讓CPU參與進來。

實際上sendfile的使用場景是比較受限的,大前提是用戶態無需看到操作的數據,并且只能從文件描述符往socket中傳輸數據,而且DMA Gather Copy也需要硬件支持,那么有沒有一種不依賴硬件特性同時又能在任意兩個文件描述符之間以零拷貝方式高效傳遞數據的方法呢?

答案是肯定的!這就要說到Linux下的另一個系統調用了:splice。

Splice

這里還要再次強調一下不管是sendfile還是這里的splice系統調用,使用的大前提都是無需在用戶態看到要傳遞的數據。

讓我們再來看一下傳統的read/write方法。

在這一方法下必須將數據從內核態拷貝的用戶態,然后在從用戶態拷貝回內核態,既然用戶態無需對該數據有任何操作,那么為什么不讓數據傳輸直接在內核態中進行呢?

現在目標有了,實現方法呢?

答案是借助Linux世界中用于進程間通信的管道,pipe。

還是以網絡服務器為例,DMA把數據從磁盤拷貝到文件buf,然后將數據寫入管道,當在再次調用splice后將數據從管道讀入socket buf中,然后通過DMA發送出去,值得注意的是向管道寫數據以及從管道讀數據并沒有真正的拷貝數據,而僅僅傳遞的是該數據相關的必要信息。

你會看到,splice和sendfile是很像的,實際上后來sendfile系統調用經過改造后就是基于splice實現的,既然有splice那么為什么還要保留sendfile呢?答案很簡單,如果直接去掉sendfile,那么之前依賴該系統調用的所有程序將無法正常運行。

總結

本文介紹了很多零拷貝的優化技巧,但是注意,一定要注意,如果你的程序對性能要沒有到那種極度苛刻哪怕慢1ns都不行的時候,忘掉本文講解的這些所謂優化技巧,老老實實用read/write,相比這些所謂的技巧,內存拷貝沒有那么糟糕。

 

本文僅僅告訴你為了追求高性能系統中都有哪些亂七八糟的設計。

 

責任編輯:武曉燕 來源: 碼農的荒島求生
相關推薦

2025-03-24 10:11:06

SpringJava開發

2019-10-12 09:35:37

程序員人生第一份工作大學

2015-11-23 17:27:19

程序員寫代碼

2020-02-28 19:10:40

Linux零拷貝原理

2021-07-26 09:43:24

代碼MapStructs項目

2020-09-26 21:23:26

程序員代碼編程

2010-10-09 09:20:08

.NET

2020-05-29 10:18:58

python開發代碼

2019-11-08 13:57:53

程序員Excel軟件

2018-05-07 15:59:39

代碼程序員重寫

2015-07-27 15:27:11

程序員重寫代碼

2015-07-28 10:28:54

程序員代碼

2017-06-12 15:53:40

程序員代碼編程

2009-05-26 09:00:59

ScalaJava面向對象

2014-12-26 10:13:41

程序員

2012-02-22 14:21:18

2013-01-22 13:50:11

程序員前端Web

2021-10-07 23:13:25

手機性能技術

2016-12-01 13:40:37

2010-12-20 09:26:44

SQL索引
點贊
收藏

51CTO技術棧公眾號

国产精品扒开腿爽爽爽视频| 美女福利视频在线| 亚洲人精品午夜| 成人在线观看免费网站| 亚洲乱码日产精品bd在线观看| 亚洲视频 欧洲视频| 超碰97免费在线| 午夜激情福利在线| 亚洲高清在线观看| 午夜欧美在线| 青娱乐国产在线视频| 欧美一级免费视频| 国产一区二区伦理| 俄罗斯嫩小性bbwbbw| 明星裸体视频一区二区| 尤物在线观看一区| 日韩成人一区| 大地资源高清在线视频观看| 午夜精品久久久久久99热软件| 日韩电影在线观看一区| 亚洲国产福利视频| 在线免费一区| 精品视频在线视频| 一区三区在线欧| 亚洲国产成人精品激情在线| av电影成人| 一个色综合网站| 4438全国亚洲精品观看视频| tube国产麻豆| 国产精品12| 亚洲一区二区高清| 91成人在线精品视频| 日本三级网站在线观看| 国产三级精品在线不卡| 天天影视色香欲综合网老头| 超碰97久久| 亚洲s码欧洲m码国产av| www.久久草| 亚洲高清免费视频| 日韩在线观看一区二区三区| 国产精久久久久久| 日本在线高清视频一区| 欧美性猛交xxxxxx富婆| 色婷婷综合网| 国产精品久久777777换脸| 99精品一区二区三区的区别| 亚洲国产精品999| 日韩高清在线观看| 1024在线播放| 丰满圆润老女人hd| 成人欧美一区二区三区在线| 一区二区三区中文字幕精品精品 | 久久亚洲精品伦理| 在线a人片免费观看视频| 黑人巨大猛交丰满少妇| 日韩美女中文字幕| 亚洲一区在线观看网站| 久久精品国产大片免费观看| 亚洲va久久久噜噜噜无码久久| 国产高清精品在线观看| 亚洲网在线观看| 国产一区二区导航在线播放| 国产高清不卡| 国产网友自拍视频| 美女在线免费视频| 中文字幕亚洲综合久久| 久久先锋影音av鲁色资源| 成人精品毛片| japanese国产| 国产女同无遮挡互慰高潮91| 国产精品久久视频| 亚洲国产一区二区在线播放| 久久激情电影| 免费黄色在线| 夜夜春很很躁夜夜躁| 手机在线观看国产精品| 亚洲香蕉成视频在线观看| 久久久精品免费网站| 国产精品白丝av嫩草影院| 亚洲精品久久久蜜桃动漫| 日本少妇激三级做爰在线| 青青草精品毛片| 午夜精品久久久久久不卡8050| 一区在线播放| 欧美日韩国产观看视频| 波多野结衣毛片| 乱妇乱女熟妇熟女网站| 日韩成人免费电影| 夜夜躁狠狠躁日日躁av| 99久re热视频精品98| 日日摸夜夜添一区| 中文字幕成人av| 欧美成人tv| mm视频在线视频| 中文字幕在线欧美| 日本在线一二三区| 成人黄动漫网站免费| 亚洲美女在线观看| 国产精品国产三级国产专播品爱网| 久久久久久久久久久久久久| 亚洲区欧洲区| 日本视频www| 六月丁香婷婷激情| 日本免费久久高清视频| 欧美在线免费视屏| 国产福利一区在线观看| 成人看片毛片免费播放器| 国产一区二区视频网站| 一二三av在线| 亚洲欧洲精品一区二区| 精品国产依人香蕉在线精品| 亚洲精选视频免费看| 影音先锋久久久| 欧美sm一区| 人妻91麻豆一区二区三区| 男人的天堂av网| 日韩在线观看a| 国产91ⅴ在线精品免费观看| 欧美精选一区二区| 韩国一区二区三区| 99国产精品久久一区二区三区| 男人的天堂av高清在线| 欧美日韩黄色网| 国产96在线 | 亚洲| 国产精品三级美女白浆呻吟| 日韩电影免费观看中文字幕 | 日韩资源在线观看| 色婷婷综合久久久| 99久久国产免费看| 66视频精品| 哺乳挤奶一区二区三区免费看| 婷婷在线视频| 天天操天天爽天天干| 中日韩精品一区二区三区| 那种视频在线观看| 色女人综合av| 欧美与黑人午夜性猛交久久久| 日韩电视剧在线观看免费网站| 亚洲视频 欧洲视频| jvid一区二区三区| ,亚洲人成毛片在线播放| 国产特级黄色录像| 日韩视频免费在线播放| 国产一区在线观| 日韩中文字幕国产精品| 91麻豆精品91久久久久同性| 亚洲国产精品一区二区www在线| 日韩高清不卡一区二区三区| 久久国产成人精品| 男人的天堂久久| 成人免费视频观看| 国内小视频在线看| 九色视频成人自拍| 99久久精品国产成人一区二区| 日本一区二区免费在线观看| 久久久久无码精品国产sm果冻| 99九九99九九九99九他书对| 欧美成人免费在线视频| 欧美三级日韩在线| 国产欧美日本一区视频| 成人午夜私人影院| 日本va欧美va瓶| 免费在线日韩av| 一区在线视频| 伊人亚洲综合网| 免费无码毛片一区二区app| 日本xxxxxxxxx18| 久久久男人的天堂| 中文字幕线观看| 中日韩av在线播放| 激情五月俺来也| 欧美日韩中文在线视频| 每日在线观看av| 在线观看18视频网站| 色综合电影网| 日韩欧美亚洲在线| 久久久av一区| 午夜成人免费视频| 亚洲国产va精品久久久不卡综合| 中文av一区二区| 欧美激情中文不卡| 国内精品免费在线观看| 狠狠色丁香久久婷婷综合_中 | 91黄色免费版| 色综合夜色一区| 亚洲自拍偷拍av| 香蕉影视欧美成人| 色先锋久久av资源部| 午夜私人影院久久久久| 欧美性xxxx极品hd满灌| 亚洲国产精品久久久久秋霞影院| 国产欧美一区二区三区鸳鸯浴| 丁香激情综合五月| 国产欧美日韩精品一区| 中文字幕亚洲在| 曰韩精品一区二区| 欧美日韩国产色| 婷婷精品在线| 一呦二呦三呦国产精品| 日本不卡免费一区| 日韩深夜福利| 国产精品av久久久久久麻豆网| 亚洲先锋成人| 久久久久国产精品一区二区| 蜜臀va亚洲va欧美va天堂| 免费观看久久久4p| 爽爽淫人综合网网站| 国产寡妇亲子伦一区二区| 久久亚洲综合av| 亚洲国产精品久久艾草纯爱| 欧美最新大片在线看| 337p亚洲精品色噜噜狠狠| 欧美精品日韩一本| 亚洲国产精品久久久| 亚洲精品少妇网址| 久久久久在线观看| 国内精品400部情侣激情| 欧美一级视频免费在线观看| 91久久嫩草影院一区二区| 久久国产一区二区| 国产成人精品免费看在线播放| 丁香啪啪综合成人亚洲| 黄页网站在线看| 免费成人深夜夜行网站| 五月天婷婷久久| 男人av在线| www青青草原| 中文字幕乱码人妻二区三区| 九色网友自拍视频手机在线| 国产精选在线| 综合伊人久久| 国产日韩欧美高清免费| 91啪亚洲精品| 一本到不卡免费一区二区| 欧美成人一区二区三区| 久久成人国产精品| 成人网欧美在线视频| 久久久久高清| 国产精品国产三级国产专区51| 尤蜜粉嫩av国产一区二区三区| 中文在线观看免费视频| 妺妺窝人体色www聚色窝仙踪| 免费观看国产视频| 性欧美hd调教| 国产在线不卡| 国产色综合一区| 欧美唯美清纯偷拍| 欧美情侣性视频| 精品国产91亚洲一区二区三区www| 亚洲熟妇国产熟妇肥婆| 一级片久久久久| 国产精品无码久久久久成人app| 精品日韩av| 四季av在线一区二区三区| 成人av中文字幕| 色综合久久中文字幕| 欧美黄色片视频| 精品国产福利| 99九九99九九九99九他书对| 亚洲色图久久久| 性一交一黄一片| 一区二区视频免费| 色戒汤唯在线观看| 欧美三区视频| 亚洲日本一区二区| 伊人久久大香线蕉av一区二区| 成人免费91在线看| 熟妇无码乱子成人精品| 中文字幕乱码无码人妻系列蜜桃| 免费在线看污片| 午夜视频一区| 一区二区三区四区av| 精品噜噜噜噜久久久久久久久试看| 国产精品吹潮在线观看| 国产精品无码av在线播放| 超碰97av在线| 欧美拍拍视频| 亚洲另类春色校园小说| 久久先锋影音av| 精品国产伦一区二区三区观看方式 | 国产精品免费看片| 亚洲色图久久久| 国产精品亚洲综合久久| 欧美一级片中文字幕| 日日摸夜夜添夜夜添精品视频| 欧美男女交配视频| 久久97超碰国产精品超碰| av免费一区二区| 粉嫩aⅴ一区二区三区四区| 美女精品视频一区| 国产黄色一区二区| 日韩精品在线视频观看| 欧美xxx.com| 中文字幕av一区| 97caopron在线视频| 欧美乱大交xxxxx另类电影| 成人bbav| 日韩美女激情视频| 久久伊人国产| 99视频日韩| 精品国产乱码久久久久久果冻传媒 | 精品在线一区| 色欧美自拍视频| 丁香六月激情婷婷| 性8sex亚洲区入口| 亚洲精品久久久久久宅男| 盗摄精品av一区二区三区| 山东少妇露脸刺激对白在线| 一区二区三区国产豹纹内裤在线| 久草精品视频在线观看| 欧美在线综合视频| 国产一级18片视频| 91精品国产免费久久综合| 亚洲av成人精品毛片| 亚洲人成网在线播放| 黄黄的网站在线观看| 国内精品久久久久久影视8| 黄色成人在线观看网站| 久久久福利视频| 五月天久久777| 久久综合九色综合88i| 国产精品18久久久久久久网站| 中文字幕国产专区| 精品久久久久人成| 国产人妖一区二区三区| 国产一区av在线| 福利成人导航| 成人激情在线播放| 日本精品三区| 91九色丨porny丨国产jk| 国内一区二区视频| 国产精品无码无卡无需播放器| 亚洲乱码中文字幕综合| 免费av中文字幕| 亚洲精品白浆高清久久久久久| 国产91在线视频蝌蚪| 国产精品毛片a∨一区二区三区|国| 美日韩黄色大片| 国产精品国产三级国产专区51| 免费观看在线色综合| 亚洲精品91在线| 91国产福利在线| 成人性生交大片免费看午夜| 精品欧美一区二区三区| xxxx18hd亚洲hd捆绑| 国产成人在线看| 在线观看美女av| 91麻豆精品国产91久久久久久| 欧美xxx.com| 国产成人精品免高潮费视频| 日韩极品在线| 久久久一本精品99久久精品| 亚洲一区二区免费看| 精品伦一区二区三区| 亚洲自拍另类综合| 国产成人精品av在线观| 不卡伊人av在线播放| 亚洲香蕉久久| 清纯唯美一区二区三区| 奇米影视在线99精品| 精品无码在线视频| 91成人免费在线| 亚洲欧美丝袜中文综合| 日韩在线国产精品| 欧美成人免费播放| 大桥未久一区二区三区| 欧美在线黄色| 日本久久久久久久久久| 一区二区三区日韩欧美| 欧美日韩一级黄色片| 亚洲一区二区黄| 午夜无码国产理论在线| 亚洲成人网上| 首页欧美精品中文字幕| 久久成人小视频| 欧美一二三区在线| 绿色成人影院| 麻豆精品蜜桃一区二区三区| 日韩不卡在线观看日韩不卡视频| 国产农村妇女精品一区| 欧美日韩日本视频| 在线中文字幕电影| 91在线观看网站| 久久黄色影院| ass极品国模人体欣赏| 日韩一区二区三区免费看| 免费在线看污片| 日本欧美色综合网站免费| 蜜桃一区二区三区在线| 九九九在线视频| 日韩国产精品亚洲а∨天堂免| 中文字幕在线免费观看视频| 午夜老司机精品| 国产91精品一区二区麻豆亚洲| 少妇愉情理伦三级| 91精品国产黑色紧身裤美女| 在线毛片观看| 欧美高清性xxxxhdvideosex| 久久精品99久久久| 久久婷婷国产麻豆91|