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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

计算机组成原理:DMA

發(fā)布時間:2024/1/18 编程问答 48 豆豆
生活随笔 收集整理的這篇文章主要介紹了 计算机组成原理:DMA 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

引入

過去幾年里,整個計算機產(chǎn)業(yè),都在嘗試不停地提升IO設備的速度。但是,無論IO速度怎么提升,比如CPU,總還是太慢。SSD 硬盤的 IOPS 可以到 2 萬、4 萬,但是我們 CPU 的主頻有 2GHz 以上,也就意味著每秒會有 20 億次的操作。

如果我們對于IO的操作,都是由CPU發(fā)出對應的指令,然后等待IO設備完成操作之后返回,那CPU就會有大量的時間其實都是在等待IO設備完成操作。

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

因此,計算機工程師們,就發(fā)明了 DMA 技術,也就是直接內存訪問(Direct MemoryAccess)技術,來減少CPU等待的時間

DMA,一個協(xié)處理器

本質上,DMA技術就是我們在主板上放一塊獨立的芯片。在進行內存和IO設備的數(shù)據(jù)傳輸?shù)臅r候,我們不再通過CPU來控制數(shù)據(jù)傳輸,而是直接通過DMA控制器(DMA Controller,簡稱 DMAC)。這塊芯片,我們可以認為它其實就是一個協(xié)處理器(Co-Processor)。

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

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

DMAC 是一塊“協(xié)處理器芯片”,這里的“協(xié)”,指的是"協(xié)助"CPU,完成對應的數(shù)據(jù)傳輸工作。在DMAC控制數(shù)據(jù)傳輸?shù)倪^程中,我們還是需要CPU的。

除此之外,DMAC也是一個特殊的IO設備。它和CPU以及其他IO設備一樣,通過連接到總線來進行實際的數(shù)據(jù)傳輸。總線上的設備呢,其實有兩種類型。一種我們稱之為主設備(Master),另外一種,我們稱之為從設備(Slave)。

  • 想要主動發(fā)起數(shù)據(jù)傳輸,必須要是一個主設備來可以,CPU就是主設備。而我們從設備(比如硬盤)只能接收數(shù)據(jù)傳輸
  • 所以,如果通過CPU來傳輸數(shù)據(jù),要么是CPU從IO設備讀數(shù)據(jù),要么是CPU向IO設備寫數(shù)據(jù)

那我們的 I/O 設備不能向主設備發(fā)起請求么?可以是可以,不過這個發(fā)送的不是數(shù)據(jù)內容,而是控制信號。IO設備可以告訴CPU,我這里有數(shù)據(jù)要傳輸給你,但是實際數(shù)據(jù)是CPU從 I/O 設備拉走的,而不是 I/O 設備推給 CPU 的。

不過,DMAC 就很有意思了,它既是一個主設備,又是一個從設備。對于 CPU 來說,它是一個從設備;對于硬盤這樣的 IO 設備來說呢,它又變成了一個主設備。那使用 DMAC進行數(shù)據(jù)傳輸?shù)倪^程究竟是什么樣的呢?下面我們來具體看看。

  • 首先,CPU 還是作為一個主設備,向 DMAC 設備發(fā)起請求。這個請求,其實就是在DMAC 里面修改配置寄存器。
  • CPU修改DMAC的配置的時候,會告訴DMAC這樣幾個信息
    • 首先是源地址的初始值和傳輸時候的地址增減方式
      • 所謂源地址,就是數(shù)據(jù)要從哪里傳輸過來。如果我們要從內存里面寫入數(shù)據(jù)到硬盤上,那么就是要讀取的數(shù)據(jù)在內存里面的地址。如果是從硬盤讀取數(shù)據(jù)到內存,那么就是硬盤的IO接口的地址
      • IO的地址可以是一個內存地址,也可以是一個端口地址。而地址的增減就是說,數(shù)據(jù)時從大的地址向小的地址傳輸,還是從小的地址向大的地址傳輸
    • 其次就是目標地址(數(shù)據(jù)傳輸?shù)哪康牡?#xff09;初始值和傳輸時候的地址增減方式
    • 第三個自然是要傳輸?shù)臄?shù)據(jù)長度,也就是我們一共要傳輸多少數(shù)據(jù)
  • 設置完這些信息之后,DMAC就會變成一個空閑的狀態(tài)(Idle)
  • 如果我們要從硬盤上往內存里面加載數(shù)據(jù),這個時候,硬盤就會向 DMAC 發(fā)起一個數(shù)據(jù)傳輸請求。這個請求并不是通過總線,而是通過一個額外的連線
  • 然后,我們的 DMAC 需要再通過一個額外的連線響應這個申請。
  • 于是,DMAC 這個芯片,就向硬盤的接口發(fā)起要總線讀的傳輸請求。數(shù)據(jù)就從硬盤里面,讀到了 DMAC 的控制器里面。
  • 然后,DMAC 再向我們的內存發(fā)起總線寫的數(shù)據(jù)傳輸請求,把數(shù)據(jù)寫入到內存里面。
  • DMAC 會反復進行上面第 6、7 步的操作,直到 DMAC 的寄存器里面設置的數(shù)據(jù)長度傳輸完成。
  • 數(shù)據(jù)傳輸完成之后,DMAC 重新回到第 3 步的空閑狀態(tài)。

  • 所以,整個數(shù)據(jù)傳輸?shù)倪^程中,我們不是通過CPU來搬運數(shù)據(jù),而是由DMAC這個芯片來搬運數(shù)據(jù)。但是CPU在這個過程中也是必不可少的。因為傳輸什么數(shù)據(jù),從哪里傳輸?shù)侥睦?#xff0c;其實還是由CPU來設置的。這也是為什么,DMAC叫做“協(xié)處理器”

    最早,計算機里是沒有 DMAC 的,所有數(shù)據(jù)都是由 CPU 來搬運的。隨著對于數(shù)據(jù)傳輸?shù)男枨笤絹碓蕉?#xff0c;先是出現(xiàn)了主板上獨立的 DMAC 控制器。到了今天,各種 I/O 設備越來越
    多,數(shù)據(jù)傳輸?shù)男枨笤絹碓綇碗s,使用的場景各不相同。加之顯示器、網(wǎng)卡、硬盤對于數(shù)據(jù)傳輸?shù)男枨蠖疾灰粯?#xff0c;所以各個設備里面都有自己的 DMAC 芯片了。

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

    了解了 DMAC 是怎么回事兒,那你可能要問了,這和我們實際進行程序開發(fā)有什么關系呢?有什么 API,我們直接調用一下,就能加速數(shù)據(jù)傳輸,減少 CPU 占用嗎?

    過去幾年的大數(shù)據(jù)浪潮里面,還真有一個開源項目很好地利用了 DMA 的數(shù)據(jù)傳輸方式,通過 DMA 的方式實現(xiàn)了非常大的性能提升。這個項目就是Kafka。下面我們就一起來看看它究竟是怎么利用 DMA 的。

    • Kafka 是目前實時數(shù)據(jù)傳輸管道的標準解決方案。
    • Kafka是一個用來處理實時數(shù)據(jù)的管道,我們常常把它來做一個消息隊列,或者用來收集和落地海量的日志。作為一個處理實時數(shù)據(jù)和日志的管道,瓶頸自然也在IO層面
    • Kafka里面常會有兩種常見的海量數(shù)據(jù)傳輸?shù)那闆r,一種是從網(wǎng)絡中接收上游的數(shù)據(jù),然后需要落地到本地磁盤上,確保數(shù)據(jù)不丟失,另一種情況是,從本地磁盤上讀取出來,通過網(wǎng)絡發(fā)送出去。

    我們來看一看后一種情況,從磁盤讀數(shù)據(jù)發(fā)送到網(wǎng)絡上去。如果我們自己寫一個簡單的程序,最直觀的辦法,自然是用一個文件讀操作,從磁盤上把數(shù)據(jù)讀到內存里面來,然后再用一個 Socket,把這些數(shù)據(jù)發(fā)送到網(wǎng)絡上去。

    File.read(fileDesc, buf, len); Socket.send(socket, buf, len);

    在這個過程中,數(shù)據(jù)一共發(fā)生了四次傳輸?shù)倪^程,其中兩次是DMA的傳輸,另外兩次是通過CPU控制的傳輸:

    • 第一次傳輸,是從硬盤上,讀到操作系統(tǒng)內核的緩沖區(qū)。這個傳輸是通過DMA搬運的
    • 第二次傳輸,需要從內核緩沖區(qū)里面的數(shù)據(jù),復制到我們應用分配的內存里面。這個傳輸是通過CPU搬運的
    • 第三次傳輸,是要從應用的內存里面,再寫到操作系統(tǒng)的socket的緩沖區(qū)里面去。這個傳輸,還是由CPU搬運的
    • 第四次傳輸,需要再從socket緩沖區(qū)里面,寫到網(wǎng)卡的緩沖區(qū)里面去,這個傳輸也是通過DMA搬運的。


    這個時候,你可以回過頭看看這個過程。我們只是要“搬運”一份數(shù)據(jù),結果卻整整搬運了四次。而且這里面,從內核的讀緩沖區(qū)傳輸?shù)綉玫膬却胬?#xff0c;再從應用的內存里傳輸?shù)?br /> Socket 的緩沖區(qū)里,其實都是把同一份數(shù)據(jù)在內存里面搬運來搬運去,特別沒有效率。

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

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

    @Override public long transferFrom(FileChannel fileChannel, long position, long count) throws IOExecptionreturn fileChannel.transferTo(position, count, socketChannel); }

    Kafka的代碼調用了Java NIO庫,具體是FileChannel里面的transsferTo方法。我們的數(shù)據(jù)并沒有讀到中間的應用內存里面,而是直接通過channel,寫入到對應的網(wǎng)絡設備里。并且,對于socket的操作,也不是寫到socket的buffer里面,而是直接根據(jù)描述符寫到網(wǎng)卡的緩沖區(qū)里面。于是,在這個過程之中,我們只進行了兩次數(shù)據(jù)傳輸。

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

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

    這這個方法里面,我們沒有在內存層面去“復制”數(shù)據(jù),所以這個方法,也叫做“零拷貝”

    在使用了這樣的零拷貝的方法之后呢,我們傳輸同樣數(shù)據(jù)的時間,可以縮減為原來的 1/3,相當于提升了 3 倍的吞吐率。

    總結

    以上是生活随笔為你收集整理的计算机组成原理:DMA的全部內容,希望文章能夠幫你解決所遇到的問題。

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