日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

续说零拷贝(Zero-Copy) - DMA技术

發(fā)布時(shí)間:2024/4/18 编程问答 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 续说零拷贝(Zero-Copy) - DMA技术 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

如果想理解Kafaka為什么這么快,得先看DMA是什么.

DMA:

????? 無論 I/O 速度如何提升,比起 CPU,總還是太慢。SSD 硬盤的 IOPS 可以到 2 萬、4 萬,但是我們 CPU 的主頻有 2GHz 以上,也就意味著每秒會(huì)有 20 億次的操作.

如果我們對(duì)于 I/O 的操作,都是由 CPU 發(fā)出對(duì)應(yīng)的指令,然后等待 I/O 設(shè)備完成操作之后返回,那 CPU 有大量的時(shí)間其實(shí)都是在等待 I/O 設(shè)備完成操作。

但是,這個(gè) CPU 的等待,在很多時(shí)候,其實(shí)并沒有太多的實(shí)際意義。我們對(duì)于 I/O 設(shè)備的大量操作,其實(shí)都只是把內(nèi)存里面的數(shù)據(jù),傳輸?shù)?I/O 設(shè)備而已。在這種情況下,其實(shí) CPU 只是在傻等而已。特別是當(dāng)傳輸?shù)臄?shù)據(jù)量比較大的時(shí)候,比如進(jìn)行大文件復(fù)制,如果所有數(shù)據(jù)都要經(jīng)過 CPU,實(shí)在是有點(diǎn)兒太浪費(fèi)時(shí)間了。

因此,計(jì)算機(jī)工程師們,就發(fā)明了 DMA 技術(shù),也就是直接內(nèi)存訪問(Direct Memory Access)技術(shù),來減少 CPU 等待的時(shí)間。

?

理解 DMA,一個(gè)協(xié)處理器:

其實(shí) DMA 技術(shù)很容易理解,本質(zhì)上,DMA 技術(shù)就是我們?cè)谥靼迳戏乓粔K獨(dú)立的芯片。在進(jìn)行內(nèi)存和 I/O 設(shè)備的數(shù)據(jù)傳輸?shù)臅r(shí)候,我們不再通過 CPU 來控制數(shù)據(jù)傳輸,而直接通過DMA 控制器(DMA Controller,簡(jiǎn)稱 DMAC)。這塊芯片,我們可以認(rèn)為它其實(shí)就是一個(gè)協(xié)處理器(Co-Processor)。

DMAC 最有價(jià)值的地方體現(xiàn)在,當(dāng)我們要傳輸?shù)臄?shù)據(jù)特別大、速度特別快,或者傳輸?shù)臄?shù)據(jù)特別小、速度特別慢的時(shí)候。

比如說,我們用千兆網(wǎng)卡或者硬盤傳輸大量數(shù)據(jù)的時(shí)候,如果都用 CPU 來搬運(yùn)的話,肯定忙不過來,所以可以選擇 DMAC。而當(dāng)數(shù)據(jù)傳輸很慢的時(shí)候,DMAC 可以等數(shù)據(jù)到齊了,再發(fā)送信號(hào),給到 CPU 去處理,而不是讓 CPU 在那里忙等待。

?DMAC數(shù)據(jù)傳輸?shù)倪^程:

?

1. 首先,CPU 還是作為一個(gè)主設(shè)備,向 DMAC 設(shè)備發(fā)起請(qǐng)求。這個(gè)請(qǐng)求,其實(shí)就是在 DMAC 里面修改配置寄存器。

2.CPU 修改 DMAC 的配置的時(shí)候,會(huì)告訴 DMAC 這樣幾個(gè)信息:

  • 首先是源地址的初始值以及傳輸時(shí)候的地址增減方式
    所謂源地址,就是數(shù)據(jù)要從哪里傳輸過來。如果我們要從內(nèi)存里面寫入數(shù)據(jù)到硬盤上,那么就是要讀取的數(shù)據(jù)在內(nèi)存里面的地址。如果是從硬盤讀取數(shù)據(jù)到內(nèi)存里,那就是硬盤的 I/O 接口的地址。
    我們講過總線的時(shí)候說過,I/O 的地址可以是一個(gè)內(nèi)存地址,也可以是一個(gè)端口地址。而地址的增減方式就是說,數(shù)據(jù)是從大的地址向小的地址傳輸,還是從小的地址往大的地址傳輸。
  • 其次是目標(biāo)地址初始值和傳輸時(shí)候的地址增減方式。目標(biāo)地址自然就是和源地址對(duì)應(yīng)的設(shè)備,也就是我們數(shù)據(jù)傳輸?shù)哪康牡亍?/li>
  • 第三個(gè)自然是要傳輸?shù)臄?shù)據(jù)長(zhǎng)度,也就是我們一共要傳輸多少數(shù)據(jù)。

3. 設(shè)置完這些信息之后,DMAC 就會(huì)變成一個(gè)空閑的狀態(tài)(Idle)。

4. 如果我們要從硬盤上往內(nèi)存里面加載數(shù)據(jù),這個(gè)時(shí)候,硬盤就會(huì)向 DMAC 發(fā)起一個(gè)數(shù)據(jù)傳輸請(qǐng)求。這個(gè)請(qǐng)求并不是通過總線,而是通過一個(gè)額外的連線。

5. 然后,我們的 DMAC 需要再通過一個(gè)額外的連線響應(yīng)這個(gè)申請(qǐng)。

6. 于是,DMAC 這個(gè)芯片,就向硬盤的接口發(fā)起要總線讀的傳輸請(qǐng)求。數(shù)據(jù)就從硬盤里面,讀到了 DMAC 的控制器里面。

7. 然后,DMAC 再向我們的內(nèi)存發(fā)起總線寫的數(shù)據(jù)傳輸請(qǐng)求,把數(shù)據(jù)寫入到內(nèi)存里面。

8.DMAC 會(huì)反復(fù)進(jìn)行上面第 6、7 步的操作,直到 DMAC 的寄存器里面設(shè)置的數(shù)據(jù)長(zhǎng)度傳輸完成。

9. 數(shù)據(jù)傳輸完成之后,DMAC 重新回到第 3 步的空閑狀態(tài)。

所以,整個(gè)數(shù)據(jù)傳輸?shù)倪^程中,我們不是通過 CPU 來搬運(yùn)數(shù)據(jù),而是由 DMAC 這個(gè)芯片來搬運(yùn)數(shù)據(jù)。但是 CPU 在這個(gè)過程中也是必不可少的。因?yàn)閭鬏斒裁磾?shù)據(jù),從哪里傳輸?shù)侥睦?#xff0c;其實(shí)還是由 CPU 來設(shè)置的。

為什么那么快?一起來看 Kafka 的實(shí)現(xiàn)原理

Kafka 是一個(gè)用來處理實(shí)時(shí)數(shù)據(jù)的管道,我們常常用它來做一個(gè)消息隊(duì)列,或者用來收集和落地海量的日志。作為一個(gè)處理實(shí)時(shí)數(shù)據(jù)和日志的管道,瓶頸自然也在 I/O 層面。

從磁盤讀數(shù)據(jù)發(fā)送到網(wǎng)絡(luò)上去,數(shù)據(jù)一共發(fā)生了四次傳輸?shù)倪^程。其中兩次是 DMA 的傳輸,另外兩次,則是通過 CPU 控制的傳輸:

?

第一次傳輸,是從硬盤上,讀到操作系統(tǒng)內(nèi)核的緩沖區(qū)里。這個(gè)傳輸是通過 DMA 搬運(yùn)的。

第二次傳輸,需要從內(nèi)核緩沖區(qū)里面的數(shù)據(jù),復(fù)制到我們應(yīng)用分配的內(nèi)存里面。這個(gè)傳輸是通過 CPU 搬運(yùn)的。

第三次傳輸,要從我們應(yīng)用的內(nèi)存里面,再寫到操作系統(tǒng)的 Socket 的緩沖區(qū)里面去。這個(gè)傳輸,還是由 CPU 搬運(yùn)的。

最后一次傳輸,需要再從 Socket 的緩沖區(qū)里面,寫到網(wǎng)卡的緩沖區(qū)里面去。這個(gè)傳輸又是通過 DMA 搬運(yùn)的。

像 Kafka 這樣的應(yīng)用場(chǎng)景,其實(shí)大部分最終利用到的硬件資源,其實(shí)又都是在干這個(gè)搬運(yùn)數(shù)據(jù)的事兒。所以,我們就需要盡可能地減少數(shù)據(jù)搬運(yùn)的需求。

事實(shí)上,Kafka 做的事情就是,把這個(gè)數(shù)據(jù)搬運(yùn)的次數(shù),從上面的四次,變成了兩次,并且只有 DMA 來進(jìn)行數(shù)據(jù)搬運(yùn),而不需要 CPU。

Kafka 的代碼調(diào)用了 Java NIO 庫,具體是 FileChannel 里面的 transferTo 方法。我們的數(shù)據(jù)并沒有讀到中間的應(yīng)用內(nèi)存里面,而是直接通過 Channel,寫入到對(duì)應(yīng)的網(wǎng)絡(luò)設(shè)備里。并且,對(duì)于 Socket 的操作,也不是寫入到 Socket 的 Buffer 里面,而是直接根據(jù)描述符(Descriptor)寫入到網(wǎng)卡的緩沖區(qū)里面。于是,在這個(gè)過程之中,我們只進(jìn)行了兩次數(shù)據(jù)傳輸。

第一次,是通過 DMA,從硬盤直接讀到操作系統(tǒng)內(nèi)核的讀緩沖區(qū)里面。第二次,則是根據(jù) Socket 的描述符信息,直接從讀緩沖區(qū)里面,寫入到網(wǎng)卡的緩沖區(qū)里面。

這樣,我們同一份數(shù)據(jù)傳輸?shù)拇螖?shù)從四次變成了兩次,并且沒有通過 CPU 來進(jìn)行數(shù)據(jù)搬運(yùn),所有的數(shù)據(jù)都是通過 DMA 來進(jìn)行傳輸?shù)摹?/p>

在這個(gè)方法里面,我們沒有在內(nèi)存層面去“復(fù)制(Copy)”數(shù)據(jù),所以這個(gè)方法,也被稱之為零拷貝(Zero-Copy)。無論傳輸數(shù)據(jù)量的大小,傳輸同樣的數(shù)據(jù),使用了零拷貝能夠縮短 65% 的時(shí)間,大幅度提升了機(jī)器傳輸數(shù)據(jù)的吞吐量。

在 Kafka 里,通過 Java 的 NIO 里面 FileChannel 的 transferTo 方法調(diào)用,我們可以不用把數(shù)據(jù)復(fù)制到我們應(yīng)用程序的內(nèi)存里面。通過 DMA 的方式,我們可以把數(shù)據(jù)從內(nèi)存緩沖區(qū)直接寫到網(wǎng)卡的緩沖區(qū)里面。在使用了這樣的零拷貝的方法之后呢,我們傳輸同樣數(shù)據(jù)的時(shí)間,可以縮減為原來的 1/3,相當(dāng)于提升了 3 倍的吞吐率。

與50位技術(shù)專家面對(duì)面20年技術(shù)見證,附贈(zèng)技術(shù)全景圖

總結(jié)

以上是生活随笔為你收集整理的续说零拷贝(Zero-Copy) - DMA技术的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。