天天看點

CUDA-全局記憶體的差別與用法

CUDA程式設計中全局記憶體分為分頁記憶體,固定記憶體,零拷貝記憶體,統一虛拟尋址,統一記憶體位址。

一.分頁記憶體

   利用malloc()申請的主機記憶體,即可分頁記憶體。

   特點:可分頁記憶體傳輸資料到裝置時,首先需要配置設定固定記憶體,再傳遞到裝置端。

            對主機而言,分頁記憶體可提高主機性能。

float* data;
malloc((void**)&data,sizeof(float)*N);
           

二.固定記憶體(pinned)- 鎖頁記憶體

    利用cudaMallocHost()申請固定記憶體。

    特點:裝置可直接通路固定記憶體,可提高傳輸性能,如圖所示。

float*data;
cudaMallocHost((void**)&data,sizeof(float)*N);           
CUDA-全局記憶體的差別與用法

三.零拷貝記憶體

     利用cudaHostAlloc()申請零拷貝記憶體。使用情況:(1)裝置不足時,可利用主機記憶體;(2)避免裝置和主機間的顯式傳輸;   (3)提高PCI-e傳輸率。

     特點:通常,主機無法通路裝置變量,裝置無法通路主機變量,但主機和裝置均可通路零拷貝記憶體。

float* data;
cudaHostAlloc((void**)&data,N*sizeof(float),unsigned int flags);           

   flags有4種:cudaHostAllocDefalt,

cudaHostAllocPortable,

cudaHostAllocWriteCombined,

cudaHostAllocMapped。

   最後一種标示就是零拷貝記憶體。

使用方式:

  1.主機通路零拷貝記憶體:直接使用可以。

  2.裝置通路零拷貝記憶體:利用cudaGetDevicePointer((void**)&DevicePtr,void* HostPtr,unsiged int flag)擷取裝置零拷貝主機記憶體對應的裝置指針,然後将裝置指針傳入kernel函數。裝置就可直接通路主機記憶體了。

四.統一虛拟位址

     利用cudaHostAlloc()擷取的零拷貝記憶體,在UVA(統一虛拟位址)之前,核函數使用的指針必須為經過cudaGetDevicePointer()獲得的裝置指針。而有了UVA之後,則省去了這一步,核函數可直接使用主機指針。

如圖所示。

CUDA-全局記憶體的差別與用法

五.統一記憶體位址

    利用cudaMallocManaged()申請托管記憶體,“統一記憶體”建立了一個托管記憶體池,記憶體池中已配置設定的空間,可以用相同的記憶體位址(指針)在CPU和GPU上進行通路。

float* data;
cudaMallocManaged((void**)&data,sizeof(float)*N,unsiged int flags)           

   特點:完成了主機與裝置資料的自動拷貝,消除重複指針。

CUDA-全局記憶體的差別與用法

繼續閱讀