日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
包教包會(huì)的零拷貝,你會(huì)了嗎?

我們接下來(lái)從下面這幾個(gè)問(wèn)題的角度來(lái)給全方面分析零拷貝這個(gè)技術(shù)點(diǎn),一邊讀不懂的同學(xué),趕緊收藏,讀多幾遍就懂了

還有還有,收藏起來(lái),等以后忘記了或者快要面試的時(shí)候,可以逃出來(lái)熟悉熟悉

畢竟,好記性不如爛筆頭的嘞

為什么要有 DMA 技術(shù)?

我們先來(lái)看一下在沒(méi)有DMA技術(shù)之前的IO過(guò)程:

1、CPU發(fā)出對(duì)應(yīng)的指令到磁盤(pán)系統(tǒng),然后返回

2、磁盤(pán)系統(tǒng)收到指令,把數(shù)據(jù)放入到磁盤(pán)系統(tǒng)的內(nèi)部緩沖區(qū)中,然后產(chǎn)生一個(gè)中斷指令

3、CPU收到中斷信號(hào),停止當(dāng)前工作,緊接著把磁盤(pán)系統(tǒng)緩沖區(qū)中的數(shù)據(jù)讀到自己的寄存器內(nèi),然后把寄存器的數(shù)據(jù)寫(xiě)入到內(nèi)存,在此數(shù)據(jù)傳輸期間CPU無(wú)法執(zhí)行其它工作

畫(huà)了一個(gè)圖幫助大家理解

聰明的小伙伴已經(jīng)發(fā)現(xiàn)其中的弊端了,就是數(shù)據(jù)傳輸期間,CPU無(wú)法執(zhí)行其它命令

我們知道CPU是中央處理器,這個(gè)東西的性能能省就省,能扣著點(diǎn)用就扣著點(diǎn)用,畢竟整個(gè)機(jī)器都要用這家伙

簡(jiǎn)單的搬運(yùn)幾個(gè)字符數(shù)據(jù)肯定沒(méi)啥問(wèn)題,但是如果傳輸大量數(shù)據(jù)的時(shí)候都需要CPU來(lái)搬運(yùn),那就很糟糕了

于是,DMA技術(shù)就誕生了,就是直接內(nèi)存訪問(wèn)技術(shù)Direct Memory Access

DMA技術(shù),就是在進(jìn)行IO設(shè)備和內(nèi)存之間數(shù)據(jù)傳輸?shù)臅r(shí)候,數(shù)據(jù)搬運(yùn)的工作全部交給DMA控制器,而CPU不再參與任何和數(shù)據(jù)搬運(yùn)相關(guān)的事情了,這樣就把CPU空出來(lái)了

具體來(lái)看一下使用DMA控制器的流程

1、用戶調(diào)用read,先操作系統(tǒng)發(fā)起IO請(qǐng)求,請(qǐng)求讀取數(shù)據(jù)到自己的內(nèi)存緩沖區(qū),然后進(jìn)入阻塞

2、操作系統(tǒng)收到請(qǐng)求,把IO請(qǐng)求發(fā)給了DMA,然后CPU執(zhí)行其它任務(wù),DMA發(fā)送給磁盤(pán)

3、磁盤(pán)收到IO請(qǐng)求,把數(shù)據(jù)放入到自己的緩沖區(qū),磁盤(pán)系統(tǒng)緩沖區(qū)滿的時(shí)候,向DMA發(fā)起中斷指令

4、DMA收到中斷指令,將磁盤(pán)緩沖區(qū)數(shù)據(jù)拷貝到內(nèi)核緩沖區(qū),不占用CPU

5、DMA讀取了足夠多數(shù)據(jù),發(fā)送中斷信號(hào)給CPU

6、CPU收到DMA信號(hào),知道數(shù)據(jù)準(zhǔn)備好了,將數(shù)據(jù)從內(nèi)核拷貝到用戶空間

看整個(gè)過(guò)程,發(fā)現(xiàn)CPU不再參與數(shù)據(jù)搬運(yùn)的工作,而是由DMA完成的,但是呢,CPU在這個(gè)過(guò)程也是必不可少,因?yàn)閭鬏斒裁?,從哪里傳輸?shù)侥睦镄枰狢PU來(lái)告訴DMA控制器

這就像創(chuàng)業(yè)公司,老板自己干活忙不過(guò)來(lái)了,就招了一個(gè)秘書(shū),但是,這個(gè)秘書(shū)操作什么,如何操作,還是得聽(tīng)老板的指揮

早期 DMA 只存在在主板上,如今由于 I/O 設(shè)備越來(lái)越多,數(shù)據(jù)傳輸?shù)男枨笠膊槐M相同,所以每個(gè) I/O 設(shè)備里面都有自己的 DMA 控制器。

傳統(tǒng)的傳輸文件

先來(lái)給大家簡(jiǎn)單說(shuō)一下用戶空間和內(nèi)核空間,比如我們部署一個(gè)Java程序到一臺(tái)Linux服務(wù)器上,我們可以認(rèn)為JVM的區(qū)域就是用戶空間,其余的空間就是內(nèi)核空間,用戶空間和內(nèi)核空間對(duì)于系統(tǒng)文件的操作權(quán)限是不一樣的

傳統(tǒng)的文件傳輸?shù)墓ぷ鞣绞剑簲?shù)據(jù)讀取和寫(xiě)入是從用戶空間和內(nèi)核空間來(lái)回復(fù)制,而內(nèi)核空間的數(shù)據(jù)是通過(guò)操作系統(tǒng)層面的IO接口從磁盤(pán)讀取或者寫(xiě)入

代碼通常如下,一般會(huì)需要兩個(gè)系統(tǒng)調(diào)用:

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

看這兩行代碼做了啥

兩次系統(tǒng)調(diào)用,發(fā)生了4次用戶態(tài)和內(nèi)核態(tài)的上下文切換,每次系統(tǒng)調(diào)用都得先從用戶態(tài)切換到內(nèi)核態(tài),然后等內(nèi)核態(tài)完成任務(wù),再切換回到用戶態(tài)

一次上下文的切換耗時(shí)幾十納秒到幾微秒,時(shí)間看上去很短,但是在高并發(fā)的場(chǎng)景下,這類時(shí)間就會(huì)變得不可忽視,從而影響系統(tǒng)的性能

中間還發(fā)生了4次數(shù)據(jù)拷貝,其中兩次是DMA的拷貝,DMA技術(shù)是優(yōu)化IO設(shè)備到內(nèi)核區(qū)的,另外兩次是通過(guò)CPU拷貝用戶緩沖區(qū)的

1、第一次拷貝,磁盤(pán)上的數(shù)據(jù)通過(guò)DMA技術(shù)拷貝到操作系統(tǒng)的內(nèi)核區(qū)中

2、第二次拷貝,CPU把內(nèi)核緩沖區(qū)數(shù)據(jù)拷貝到用戶緩沖區(qū)中

3、第三次拷貝,CPU將用戶緩沖區(qū)的數(shù)據(jù)搬運(yùn)到內(nèi)核緩沖區(qū)中

4、第四次拷貝,通過(guò)DMA技術(shù)把內(nèi)核數(shù)據(jù)搬運(yùn)到網(wǎng)卡的緩沖區(qū)中

問(wèn)題:我們搬運(yùn)一次數(shù)據(jù),中間卻復(fù)制了4次,過(guò)多的上下文切換和過(guò)多的數(shù)據(jù)拷貝都會(huì)降低系統(tǒng)性能,所以,如果想提高文件傳輸?shù)男阅?,就需要減少用戶態(tài)和內(nèi)核態(tài)的上下文切換和內(nèi)容拷貝的次數(shù)

優(yōu)化思路

減少用戶態(tài)和內(nèi)核態(tài)之間的上下文切換

之所以發(fā)生上下文的切換,是因?yàn)橛脩艨臻g沒(méi)有權(quán)限操作磁盤(pán)或者網(wǎng)卡,內(nèi)核的權(quán)限最高,這些操作設(shè)備的過(guò)程都需要交給操作系統(tǒng)的內(nèi)核來(lái)完成,一次系統(tǒng)調(diào)用也就意味著必然發(fā)生2次上下文的切換,首先從用戶態(tài)切換到內(nèi)核態(tài),內(nèi)核態(tài)執(zhí)行完任務(wù)之后再切換到用戶態(tài)執(zhí)行相應(yīng)進(jìn)程的代碼指令

所以,要減少上下文切換的次數(shù),就需要減少系統(tǒng)調(diào)用的次數(shù)

減少數(shù)據(jù)拷貝的次數(shù)

數(shù)據(jù)傳輸?shù)?次拷貝,其中內(nèi)核拷貝到用戶緩沖區(qū),再?gòu)挠脩艟彌_區(qū)拷貝到內(nèi)核緩沖區(qū),這兩個(gè)過(guò)程是沒(méi)必要的,因?yàn)樵谖募鬏數(shù)膽?yīng)用場(chǎng)景中,在用戶空間我們并不會(huì)對(duì)數(shù)據(jù)再加工,所以這個(gè)數(shù)據(jù)沒(méi)必要搬運(yùn)到用戶空間

如何實(shí)現(xiàn)零拷貝?

零拷貝技術(shù)實(shí)現(xiàn)的方式通常有 2 種:

mmap + write(三次拷貝+兩次系統(tǒng)調(diào)用)
Sendfile(三次拷貝+一次系統(tǒng)調(diào)用)

下面就談一談,它們是如何減少「上下文切換」和「數(shù)據(jù)拷貝」的次數(shù)。

mmap + write

在前面我們知道,read() 系統(tǒng)調(diào)用的過(guò)程中會(huì)把內(nèi)核緩沖區(qū)的數(shù)據(jù)拷貝到用戶的緩沖區(qū)里,于是為了減少這一步開(kāi)銷,我們可以用 mmap() 替換 read() 系統(tǒng)調(diào)用函數(shù)。

buf = mmap(file, len);
write(sockfd, buf, len);

mmap() 系統(tǒng)調(diào)用函數(shù)會(huì)直接把內(nèi)核緩沖區(qū)里的數(shù)據(jù)「映射」到用戶空間,這樣,操作系統(tǒng)內(nèi)核與用戶空間就不需要再進(jìn)行任何的數(shù)據(jù)拷貝操作。

具體過(guò)程如下:

1、應(yīng)用調(diào)用了mmap(),DMA把磁盤(pán)數(shù)據(jù)拷貝到內(nèi)核緩沖區(qū),此時(shí),應(yīng)用進(jìn)程和內(nèi)核會(huì)共享這個(gè)內(nèi)核緩沖區(qū)

2、應(yīng)用系統(tǒng)調(diào)用write(),操作系統(tǒng)直接把內(nèi)核緩沖區(qū)數(shù)據(jù)拷貝到網(wǎng)絡(luò)緩沖區(qū)中,這個(gè)也是屬于內(nèi)核態(tài),內(nèi)核中的拷貝,由CPU來(lái)操作

3、第三次拷貝,通過(guò)DMA技術(shù)把網(wǎng)絡(luò)緩沖區(qū)數(shù)據(jù)拷貝到網(wǎng)卡的緩沖區(qū)中

我們可以得知,通過(guò)使用mmap()來(lái)代替 read(),可以減少一次數(shù)據(jù)拷貝的過(guò)程。

但這還不是最理想的零拷貝,因?yàn)槿匀恍枰ㄟ^(guò) CPU 把內(nèi)核緩沖區(qū)的數(shù)據(jù)拷貝到 socket 緩沖區(qū)里,而且仍然需要 4 次上下文切換,因?yàn)橄到y(tǒng)調(diào)用還是 2 次。

Sendfile

在 Linux 內(nèi)核版本 2.1 中,提供了一個(gè)專門(mén)發(fā)送文件的系統(tǒng)調(diào)用函數(shù) sendfile(),函數(shù)形式如下:

#include 
ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count);

它的前兩個(gè)參數(shù)分別是目的端和源端的文件描述符,后面兩個(gè)參數(shù)是源端的偏移量和復(fù)制數(shù)據(jù)的長(zhǎng)度,返回值是實(shí)際復(fù)制數(shù)據(jù)的長(zhǎng)度。

首先,它可以替代前面的 read() 和 write() 這兩個(gè)系統(tǒng)調(diào)用,這樣就可以減少一次系統(tǒng)調(diào)用,也就減少了 2次上下文切換的開(kāi)銷。

其次,該系統(tǒng)調(diào)用,可以直接把內(nèi)核緩沖區(qū)里的數(shù)據(jù)拷貝到 socket 緩沖區(qū)里,不再拷貝到用戶態(tài),這樣就只有 2 次上下文切換,和 3 次數(shù)據(jù)拷貝。

如下圖

但是這還不是真正的零拷貝技術(shù),如果網(wǎng)卡支持 SG-DMA(The Scatter-Gather Direct Memory Access)技術(shù)(和普通的 DMA 有所不同),我們可以進(jìn)一步減少通過(guò) CPU 把內(nèi)核緩沖區(qū)里的數(shù)據(jù)拷貝到 socket 緩沖區(qū)的過(guò)程。

你可以在你的 Linux 系統(tǒng)通過(guò)下面這個(gè)命令,查看網(wǎng)卡是否支持 scatter-gather 特性:

$ ethtool -k eth0 | grep scatter-gather
scatter-gather: on

于是,從 Linux 內(nèi)核 2.4 版本開(kāi)始起,對(duì)于支持網(wǎng)卡支持 SG-DMA 技術(shù)的情況下, sendfile() 系統(tǒng)調(diào)用的過(guò)程發(fā)生了點(diǎn)變化,具體過(guò)程如下:

1、DMA直接將磁盤(pán)上的數(shù)據(jù)拷貝到內(nèi)核緩沖區(qū)中

2、緩沖區(qū)描述符和數(shù)據(jù)長(zhǎng)度傳到 socket 緩沖區(qū),這樣網(wǎng)卡的 SG-DMA 控制器就可以直接將內(nèi)核緩存中的數(shù)據(jù)拷貝到網(wǎng)卡的緩沖區(qū)里,此過(guò)程不需要將數(shù)據(jù)從操作系統(tǒng)內(nèi)核緩沖區(qū)拷貝到 socket 緩沖區(qū)中,這樣就減少了一次數(shù)據(jù)拷貝

所以,這個(gè)過(guò)程之中,只進(jìn)行了 2 次數(shù)據(jù)拷貝,如下圖:

這就是所謂的零拷貝(Zero-copy)技術(shù),因?yàn)槲覀儧](méi)有在內(nèi)存層面去拷貝數(shù)據(jù),也就是說(shuō)全程沒(méi)有通過(guò) CPU來(lái)搬運(yùn)數(shù)據(jù),所有的數(shù)據(jù)都是通過(guò) DMA 來(lái)進(jìn)行傳輸?shù)摹?/p>

CPU屬于參與了,但沒(méi)完全參與,DMA操作需要CPU指揮,描述符和數(shù)據(jù)長(zhǎng)度需要CPU發(fā)送

零拷貝技術(shù)的文件傳輸方式相比傳統(tǒng)文件傳輸?shù)姆绞剑瑴p少了 2 次上下文切換和數(shù)據(jù)拷貝次數(shù),只需要 2 次上下文切換和數(shù)據(jù)拷貝次數(shù),就可以完成文件的傳輸,而且 2 次的數(shù)據(jù)拷貝過(guò)程,都不需要通過(guò) CPU,2 次都是由 DMA 來(lái)搬運(yùn)。

我們通常說(shuō)的這個(gè)零拷貝技術(shù)中的這個(gè)零,指的是內(nèi)核態(tài)和用戶態(tài)之間的拷貝次數(shù),變成了0

所以,總體來(lái)看,零拷貝技術(shù)可以把文件傳輸?shù)男阅芴岣咧辽僖槐兑陨稀?/p>

PageCache

上面說(shuō)的第一步是先把磁盤(pán)文件數(shù)據(jù)拷貝到內(nèi)核緩沖區(qū)中,這個(gè)內(nèi)核緩沖區(qū)就是磁盤(pán)高速緩沖區(qū)PageCache,內(nèi)存速度比磁盤(pán)速度快,但是內(nèi)存空間比磁盤(pán)要小

我們需要把此時(shí)的熱點(diǎn)數(shù)據(jù)放入到緩存中,因?yàn)檫@是最近需要頻繁訪問(wèn)的,空間不足的時(shí)候淘汰掉那些訪問(wèn)頻率低的數(shù)據(jù)

緩存這些道理大家應(yīng)該都懂,零拷貝也使用了緩存技術(shù),讀取數(shù)據(jù)的時(shí)候,優(yōu)先在PageCache中找,找到直接返回,找不到去磁盤(pán)中讀取,然后緩存到PageCache中

還有一點(diǎn),讀取磁盤(pán)數(shù)據(jù)的時(shí)候,需要找到數(shù)據(jù)所在的位置,但是對(duì)于機(jī)械磁盤(pán)來(lái)說(shuō),就是通過(guò)磁頭旋轉(zhuǎn)到數(shù)據(jù)所在的扇區(qū),再開(kāi)始「順序」讀取數(shù)據(jù),但是旋轉(zhuǎn)磁頭這個(gè)物理動(dòng)作是非常耗時(shí)的,為了降低它的影響,PageCache 使用了「預(yù)讀功能」。

比如,假設(shè) read 方法每次只會(huì)讀 32 KB 的字節(jié),雖然read 剛開(kāi)始只會(huì)讀 0 ~ 32 KB 的字節(jié),但內(nèi)核會(huì)把其后面的 32~64 KB 也讀取到 PageCache,這樣后面讀取32~64 KB 的成本就很低,如果在 32~64 KB 淘汰出PageCache 前,進(jìn)程讀取到它了,收益就非常大。

所以,PageCache 的優(yōu)點(diǎn)主要是兩個(gè):

緩存最近被訪問(wèn)的數(shù)據(jù);預(yù)讀功能;

這兩個(gè)做法,將大大提高讀寫(xiě)磁盤(pán)的性能。

但是,在傳輸大文件(GB 級(jí)別的文件)的時(shí)候,PageCache 會(huì)不起作用,那就白白浪費(fèi) DMA 多做的一次數(shù)據(jù)拷貝,造成性能的降低,即使使用了PageCache 的零拷貝也會(huì)損失性能,一個(gè)大文件直接占滿,導(dǎo)致某些熱點(diǎn)小文件無(wú)法使用,性能就降低了

所以,針對(duì)大文件的傳輸,不應(yīng)該使用 PageCache,也就是說(shuō)不應(yīng)該使用零拷貝技術(shù),因?yàn)榭赡苡捎赑ageCache 被大文件占據(jù),而導(dǎo)致「熱點(diǎn)」小文件無(wú)法利用到 PageCache,這樣在高并發(fā)的環(huán)境下,會(huì)帶來(lái)嚴(yán)重的性能問(wèn)題。

對(duì)于大文件傳輸,可以通過(guò)異步IO和繞開(kāi)PageCache的IO來(lái)代替零拷貝技術(shù)

在 nginx 中,我們可以用如下配置,來(lái)根據(jù)文件的大小來(lái)使用不同的方式:

location /video/ { sendfile on; aio on; directio 1024m;}

當(dāng)文件大小大于 directio 值后,使用「異步 I/O + 直接 I/O」,否則使用「零拷貝技術(shù)」。

總結(jié)

1、早期IO,內(nèi)核數(shù)據(jù)需要IO進(jìn)行復(fù)制,2次系統(tǒng)調(diào)用,4次上下文切換,4次數(shù)據(jù)的拷貝,CPU拷貝數(shù)據(jù)期間不能執(zhí)行其它命令

2、引入DMA技術(shù),DMA可以代替CPU進(jìn)行磁盤(pán)到內(nèi)核區(qū)域數(shù)據(jù)的復(fù)制,這個(gè)期間CPU可執(zhí)行其它命令,改善了性能

3、零拷貝技術(shù):mmap+write,2次系統(tǒng)調(diào)用,4次上下文切換,3次數(shù)據(jù)的拷貝,減少了讀取期間內(nèi)核區(qū)域到用戶區(qū)域的數(shù)據(jù)復(fù)制,原因是兩者共享了內(nèi)核區(qū)域的緩沖區(qū)

4、零拷貝技術(shù):Sendfile,1次系統(tǒng)調(diào)用,2次上下文切換,3次數(shù)據(jù)的拷貝,直接指定了原文件和目標(biāo)文件,替代了原來(lái)的兩次系統(tǒng)調(diào)用,直接一次完成

5、真正的零拷貝技術(shù):網(wǎng)卡支持 SG-DMA技術(shù),數(shù)據(jù)從磁盤(pán)系統(tǒng)讀取到內(nèi)核緩沖區(qū)之后,不需要復(fù)制到相應(yīng)的socket緩沖區(qū)即可,只需要發(fā)送描述符和數(shù)據(jù)長(zhǎng)度即可,這個(gè)期間經(jīng)歷了1次系統(tǒng)調(diào)用,2次上下文切換,2次數(shù)據(jù)拷貝,沒(méi)有在內(nèi)核層面去進(jìn)行數(shù)據(jù)的拷貝

6、零拷貝技術(shù)引用PageCache緩存技術(shù),緩存技術(shù)用于加速熱點(diǎn)文件的查詢速度,但是不適用于大文件,大文件可以通過(guò)異步IO和繞開(kāi)PageCache的IO來(lái)代替零拷貝技術(shù)

參考文獻(xiàn):https://zhuanlan.zhihu.com/p/258513662

本文轉(zhuǎn)載自微信公眾號(hào)「左耳君」,可以通過(guò)以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系左耳君公眾號(hào)。


分享標(biāo)題:包教包會(huì)的零拷貝,你會(huì)了嗎?
瀏覽路徑:http://www.5511xx.com/article/dhhiphi.html