第一個cuda程式- www

文章推薦指數: 80 %
投票人數:10人

由於runtime API 較容易使用,一開始我們會以runetime API 為主。

CUDA 的初始化. 首先,先建立一個檔案first_cuda.cu。

如果是使用Visual Studio 的話,則請先按照這裡的 ... 第一個cuda程式 第一個CUDA程式 CUDA目前有兩種不同的API:RuntimeAPI和DriverAPI,兩種API各有其適用的範圍。

由於runtimeAPI較容易使用,一開始我們會以runetimeAPI為主。

CUDA的初始化首先,先建立一個檔案first_cuda.cu。

如果是使用VisualStudio的話,則請先按照這裡的設定方式設定project。

要使用runtimeAPI的時候,需要includecuda_runtime.h。

所以,在程式的最前面,加上#include#include接下來是一個InitCUDA函式,會呼叫runtimeAPI中,有關初始化CUDA的功能:boolInitCUDA(){   intcount;   cudaGetDeviceCount(&count);   if(count==0){      fprintf(stderr,"Thereisnodevice.\n");      returnfalse;   }   inti;   for(i=0;i=1){           break;         }      }   }   if(i==count){      fprintf(stderr,"ThereisnodevicesupportingCUDA1.x.\n");      returnfalse;   }   cudaSetDevice(i);   returntrue;}這個函式會先呼叫cudaGetDeviceCount函式,取得支援CUDA的裝置的數目。

如果系統上沒有支援CUDA的裝置,則它會傳回1,而device0會是一個模擬的裝置,但不支援CUDA1.0以上的功能。

所以,要確定系統上是否有支援CUDA的裝置,需要對每個device呼叫cudaGetDeviceProperties函式,取得裝置的各項資料,並判斷裝置支援的CUDA版本(prop.major和prop.minor分別代表裝置支援的版本號碼,例如1.0則prop.major為1而prop.minor為0)。

透過cudaGetDeviceProperties函式可以取得許多資料,除了裝置支援的CUDA版本之外,還有裝置的名稱、記憶體的大小、最大的thread數目、執行單元的時脈等等。

詳情可參考NVIDIA的CUDAProgrammingGuide。

在找到支援CUDA1.0以上的裝置之後,就可以呼叫cudaSetDevice函式,把它設為目前要使用的裝置。

最後是main函式。

在main函式中我們直接呼叫剛才的InitCUDA函式,並顯示適當的訊息:intmain(){   if(!InitCUDA()){      return0;   }   printf("CUDAinitialized.\n");   return0;}這樣就可以利用nvcc來compile這個程式了。

使用VisualStudio的話,若按照先前的設定方式,可以直接BuildProject並執行。

nvcc是CUDA的compile工具,它會將.cu檔拆解出在GPU上執行的部份,及在host上執行的部份,並呼叫適當的程式進行compile動作。

在GPU執行的部份會透過NVIDIA提供的compiler編譯成中介碼,而host執行的部份則會透過系統上的C++compiler編譯(在Windows上使用VisualC++而在Linux上使用gcc)。

編譯後的程式,執行時如果系統上有支援CUDA的裝置,應該會顯示CUDAinitialized.的訊息,否則會顯示相關的錯誤訊息。

利用CUDA進行運算到目前為止,我們的程式並沒有做什麼有用的工作。

所以,現在我們加入一個簡單的動作,就是把一大堆數字,計算出它的平方和。

首先,把程式最前面的include部份改成:#include#include#include#defineDATA_SIZE1048576intdata[DATA_SIZE];並加入一個新函式GenerateNumbers:voidGenerateNumbers(int*number,intsize){   for(inti=0;i>>(參數...);呼叫完後,還要把結果從顯示晶片複製回主記憶體上。

在main函式中加入以下的程式:   sumOfSquares<<<1,1,0>>>(gpudata,result);   intsum;   cudaMemcpy(&sum,result,sizeof(int),cudaMemcpyDeviceToHost);   cudaFree(gpudata);   cudaFree(result);   printf("sum:%d\n",sum);因為這個程式只使用一個thread,所以block數目、thread數目都是1。

我們也沒有使用到任何sharedmemory,所以設為0。

編譯後執行,應該可以看到執行的結果。

為了確定執行的結果正確,我們可以加上一段以CPU執行的程式碼,來驗證結果:   sum=0;   for(inti=0;i>>(gpudata,result,time);   intsum;   clock_ttime_used;   cudaMemcpy(&sum,result,sizeof(int),cudaMemcpyDeviceToHost);   cudaMemcpy(&time_used,time,sizeof(clock_t),      cudaMemcpyDeviceToHost);   cudaFree(gpudata);   cudaFree(result);   printf("sum:%dtime:%d\n",sum,time_used);編譯後執行,就可以看到執行所花費的時間了。

如果計算實際執行時間的話,可能會注意到它的執行效率並不好。

這是因為我們的程式並沒有利用到CUDA的主要的優勢,即平行化執行。

在下一段文章中,會討論如何進行最佳化的動作。

Home CUDA簡介 安裝CUDA第一個CUDA程式改良第一個程式第二個CUDA程式GPU的硬體架構Copyright(c)2007Ping-CheChen  Signin|RecentSiteActivity|ReportAbuse|PrintPage|PoweredByGoogleSites



請為這篇文章評分?