<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 手機(jī)與無線通信 > 設(shè)計(jì)應(yīng)用 > 基于GPU的AES算法實(shí)現(xiàn)

          基于GPU的AES算法實(shí)現(xiàn)

          作者: 時(shí)間:2011-06-14 來源:網(wǎng)絡(luò) 收藏


          2 CUDA編程簡(jiǎn)介
          2.1 CUDA簡(jiǎn)介
          CUDA全稱是Compute Unified Device Architecture,是NVIDIA公司在2006年11月推出的一種在上進(jìn)行通用計(jì)算的架構(gòu)。它具有全新的并行編程模型,不需要像傳統(tǒng)開發(fā)方式那樣進(jìn)行圖形API的映射就可以使用的資源進(jìn)行并行計(jì)算。CUDA是一個(gè)包含軟件和硬件的完整的并行計(jì)算架構(gòu),它的硬件設(shè)備是具有多個(gè)流處理器核的圖形并且支持CUDA的GPU,軟件部分包括編譯工具、驅(qū)動(dòng)程序、runtime庫和一些常用的數(shù)學(xué)運(yùn)算庫。
          2.2 CUDA中GPU結(jié)構(gòu)
          在CUDA架構(gòu)下,開發(fā)者可以通過創(chuàng)建和管理大量的線程來使用GPU的硬件資源進(jìn)行并行計(jì)算。在CUDA中線程的創(chuàng)建和切換是由硬件來的,不會(huì)占用軟件的執(zhí)行時(shí)間。在CUDA的rtmtime庫中提供了訪問GPU硬件資源的接口,用戶通過調(diào)用runtime庫中的函數(shù)就可以直接訪問GPU的硬件資源。CUDA的編程語言是一種C語言的擴(kuò)展,提供了通用的DRAM尋址方式,從而提供了很大的編程靈活性。操作系統(tǒng)可以管理多個(gè)并發(fā)運(yùn)行的CUDA程序和圖形應(yīng)用程序來訪問GPU。

          3 CUDA編程模型
          由于GPU的特點(diǎn),它很適合做高密度數(shù)據(jù)的并行運(yùn)算,但是對(duì)于不能并行的具有復(fù)雜執(zhí)行路徑的程序執(zhí)行效率就會(huì)很低。因此當(dāng)通過CUDA在GPU上進(jìn)行通用計(jì)算的開發(fā)時(shí),是把在應(yīng)用程序中高密度數(shù)據(jù)可以進(jìn)行并行計(jì)算的部分做成一個(gè)稱作kernel的函數(shù)在GPU設(shè)備上執(zhí)行,而應(yīng)用程序中的其他串行執(zhí)行的部分由主機(jī)上的CPU來完成。一個(gè)在GPU上執(zhí)行的kernel可以包含極高數(shù)量并發(fā)執(zhí)行的線程,在CUDA架構(gòu)中是通過設(shè)計(jì)kernel中的線程來完成通用計(jì)算的GPU的。主機(jī)和GPU設(shè)備之間的交互是通過在主機(jī)和設(shè)備各自的DRAM之間傳輸數(shù)據(jù)來的,而這種數(shù)據(jù)傳輸是由設(shè)備的DMA引擎完成的,因此數(shù)據(jù)的傳輸并不會(huì)造成太多主機(jī)CPU開銷。
          一個(gè)kernel中的線程是被分成具有相同大小的線程塊的,線程塊可以是一維、二維或者三維的,因此對(duì)應(yīng)的線程就可以具有一維、二維或者三維的索引。在一個(gè)線程塊中每個(gè)線程都具有一個(gè)一維的ID,這個(gè)ID和索引具有以下kernel關(guān)系:對(duì)于一維的線程塊,線程就等于其索引;對(duì)于大小為ID(Dx,Dy)的二維線程塊,索引為(x,y)的線程ID為(x+v Dx);對(duì)于大小為(Dx,Dy,Dz)的三維線程塊,索引為(x,y,z)的線程ID為(x+y Dx+z Dx Dy)。
          同一個(gè)線程塊中的線程之間可以通過同步操作來協(xié)同內(nèi)存訪問。當(dāng)通過調(diào)用內(nèi)置函數(shù)_syncthreads()在kernel中建立同步點(diǎn)時(shí),一個(gè)線程塊中的執(zhí)行到同步點(diǎn)的線程會(huì)被掛起直到這個(gè)線程塊中所有的線程都到達(dá)這個(gè)同步點(diǎn)。
          為了線程之間能夠有效地協(xié)同工作,同步操作被設(shè)計(jì)成只需要一條指令就可以實(shí)現(xiàn),并且同一個(gè)線程塊中的線程需要在同一個(gè)多核處理器上執(zhí)行。因此每個(gè)線程塊中全部線程的數(shù)量就受到一個(gè)處理器核上的存儲(chǔ)資源的限制。在當(dāng)前的GPU上,一個(gè)線程塊可以包含最多512個(gè)線程。
          雖然一個(gè)線程塊可以包含的線程數(shù)量有限制,但是一個(gè)kernel可以包括多個(gè)大小相同的線程塊,kernel中的線程數(shù)就等于每個(gè)塊中線程的數(shù)量乘以線程塊的數(shù)量。線程塊之間是獨(dú)立的,它們可以并行地執(zhí)行,也可以串行地順序執(zhí)行。這就允許線程塊在多個(gè)處理器核之間按照任何順序調(diào)度,從而使得開發(fā)具有靈活性和可擴(kuò)展性。而且這樣線程塊的數(shù)量就可以根據(jù)待處理數(shù)據(jù)的大小決定,而不是由系統(tǒng)中多核處理器的個(gè)數(shù)決定,也就是說線程塊的數(shù)量可以大于多核處理器的數(shù)量。因此kernel中可以具有大量的線程塊,從而具有極高的線程數(shù)。但是由于線程塊之間執(zhí)行的不確定性,不同線程塊的線程之間不能進(jìn)行同步操作。
          3.1 設(shè)計(jì)
          首先把待處理的大數(shù)據(jù)塊劃分為尺寸相同的多個(gè)小數(shù)據(jù)塊,然后使用標(biāo)準(zhǔn)的對(duì)各個(gè)小數(shù)據(jù)塊進(jìn)行并行的運(yùn)算,運(yùn)算完成后把每個(gè)小數(shù)據(jù)塊的值按順序保存在一起,最后再把所有的輸出結(jié)果使用標(biāo)準(zhǔn)的來處理得到最后的結(jié)果,這樣就可以使用大量的線程來并行地對(duì)每個(gè)小數(shù)據(jù)塊進(jìn)行運(yùn)算。但是當(dāng)數(shù)據(jù)分塊足夠多線程數(shù)很大時(shí),就需要將線程劃分為多個(gè)線程塊。由于不同線程塊中的線程之間不能進(jìn)行同步,所以設(shè)計(jì)了兩個(gè)kernel,第一個(gè)kernel的任務(wù)是使用大量并發(fā)執(zhí)行的線程對(duì)原始數(shù)據(jù)分成的多個(gè)小塊數(shù)據(jù)進(jìn)行運(yùn)算,并把結(jié)果按照順序保存在設(shè)備DKAM中。等第一個(gè)kernel執(zhí)行完成后,由主機(jī)啟動(dòng)第二個(gè)kernel,這個(gè)kernel會(huì)根據(jù)主機(jī)提供的地址和數(shù)據(jù)大小對(duì)第一個(gè)kernel的計(jì)算得到的中間值進(jìn)行運(yùn)算,這一步只需用一個(gè)線程來執(zhí)行,由于中間值的大小遠(yuǎn)遠(yuǎn)小于原始數(shù)據(jù),所以這一步的計(jì)算開銷是很小的。
          3.2 算法優(yōu)化
          GPU計(jì)算雖然高效,但是也有瓶頸。CPU代碼在調(diào)用GPU的kernel函數(shù)時(shí),首先要將內(nèi)存中的數(shù)據(jù)塊讀到流中,處理完后,又要將流寫回內(nèi)存。


          關(guān)鍵詞: 實(shí)現(xiàn) 算法 AES GPU 基于

          評(píng)論


          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();