各工具或庫的版本:
IDE:VS2008
QT:4.8.0 (使用MSVC編譯器)
CUDA:3.2
單獨使用CUDA文件在vccc下進行編譯很多書上都講過。這里主要講在QT中如何的使用CUDA,QT在VS2008環境下開發。
下面以寬為1024的舉證乘法為例,再輔以QT GUI說明如何在VS2008的QT工程中使用CUDA,VS2010沒試過,不過應該是差不多的步驟。
1.新建VS2008下QT工程
這個就不多說了,熟悉VS2008下進行QT開發的都知道怎么弄,新建一個Qt GUI程序,基類我選擇的QDialog,如下:
2.設置項目屬性
需要設置的項目屬性包括:更改生成規則(添加對CUDA文件的編譯連接支持)、添加使用CUDA需要用到的鏈接庫(.lib文件)
首先添加生成規則:右鍵工程——>自定義生成規則,添加CUDA Runtime API Build Rule (v3.2),如下圖:
然后添加鏈接庫:項目——>屬性——>鏈接器——>常規,在附加庫目錄中添加ToolKit和SDK目錄里的lib,在輸入的附加庫目錄下添加需要用到的lib文件。這一步和在單獨使用CUDA時的做法是一樣的,詳見http://www.cnblogs.com/Romi/archive/2012/04/20/2459669.html
3.編寫CUDA文件(.cu)
在項目中新建一個.cu的文件,加上如下代碼,完成在GPU設備上進行矩陣乘法:

1 //CUDAtest.cu
2
3 #include "cuda_runtime.h"
4
5 #define TILE_WIDTH 64
6
7 //核函數
8 __global__ static void MatrixMulKernel(const float* Md,const float* Nd,float* Pd,int Width)
9 {
10 //計算Pd和Md中元素的行索引
11 int Row = blockIdx.y*TILE_WIDTH+threadIdx.y; //行
12 int Col = blockIdx.x*TILE_WIDTH+threadIdx.x; //列
13
14 float Pvalue = 0.0;
15 for (int k=0;k<Width;k++)
16 {
17 Pvalue +=Md[Row*Width+k]*Nd[k*Width+Col];
18 }
19 //每個線程負責計算P中的一個元素
20 Pd[Row*Width+Col]=Pvalue;
21 }
22
23 //矩陣乘法(CUDA中)
24 //在外部調用,使用extern
25 extern "C" void MatrixMultiplication_CUDA(const float* M,const float* N,float* P,int Width)
26 {
27 cudaSetDevice(0); //設置目標GPU
28
29 float *Md,*Nd,*Pd;
30 int size = Width*Width*sizeof(float);//字節長度
31
32 cudaMalloc((void**)&Md,size);
33 cudaMalloc((void**)&Nd,size);
34 cudaMalloc((void**)&Pd,size);
35
36 //Copies a matrix from the memory* area pointed to by src to the memory area pointed to by dst
37 cudaMemcpy(Md,M,size,cudaMemcpyHostToDevice);
38 cudaMemcpy(Nd,N,size,cudaMemcpyHostToDevice);
39
40 //
41 dim3 dimGrid(Width/TILE_WIDTH,Width/TILE_WIDTH); //網格的維度
42 dim3 dimBlock(TILE_WIDTH,TILE_WIDTH); //塊的維度
43 MatrixMulKernel<<<dimGrid,dimBlock>>> (Md,Nd,Pd,Width);
44
45 cudaMemcpy(P,Pd,size,cudaMemcpyDeviceToHost);
46 //釋放設備上的矩陣
47 cudaFree(Md);
48 cudaFree(Nd);
49 cudaFree(Pd);
50 }
這里使用extern以聲明函數可以在外部被調用。如果是在調用該函數的原文件中使用include “XXX.cu”,我這會出現編譯錯誤,暫沒有解決,所以使用extern
4.在Qt響應源文件中添加CUDA的引用
Qt GUI設計如下圖,點擊“GPU計算”按鈕進行CUDA計算,后面顯示計算的時間:
源文件如下(包含用到的自定義函數和按鈕響應函數):

1 //cudainqt.cpp源文件
2
3 #include "cudainqt.h"
4 #include <QProgressDialog>
5 #include <time.h>
6
7 //這里不要忘了加引用聲明
8 extern "C" void MatrixMultiplication_CUDA(const float* M,const float* N,float* P,int Width);
9
10 //構造函數...
11 //析構函數...
12
13 //產生矩陣,矩陣中元素0~1
14 void matgen(float* a,int Width)
15 {
16 int i,j;
17 for (i=0;i<Width;i++)
18 {
19 for (j=0;j<Width;j++)
20 {
21 a[i*Width+j]=(float)rand()/RAND_MAX + (float)rand()/(RAND_MAX*RAND_MAX);
22 }
23 }
24 }
25
26 //矩陣乘法(CPU驗證)
27 void MatrixMultiplication(const float* M,const float* N,float* P,int Width)
28 {
29 QProgressDialog progress("Progress", "Cancel", 0, 100);
30 int i,j,k;
31 for (i=0;i<Width;i++)
32 {
33 for (j=0;j<Width;j++)
34 {
35 double sum=0;
36 for (k=0;k<Width;k++)
37 {
38 sum += M[i*Width+k]*N[k*Width+j];
39 }
40 P[i*Width+j]=sum;
41 }
42 if(0==i%5)
43 progress.setValue(100*i/(Width-1));
44 }
45 }
46
47 void cudaInQt::OnButtonClicked_GPU()
48 {
49 float *M,*N,*Pg;
50 int Width=1024; //1024×1024矩陣乘法
51 M=(float*)malloc(sizeof(float)*Width*Width);
52 N=(float*)malloc(sizeof(float)*Width*Width);
53 Pg=(float*)malloc(sizeof(float)*Width*Width); //保存GPU計算結果
54
55 srand(0);
56
57 matgen(M,Width); //產生矩陣M
58 matgen(N,Width); //產生矩陣N
59
60 double timeStart,timeEnd; //定義時間,求時間差用
61 timeStart = clock();
62 MatrixMultiplication_CUDA(M,N,Pg,Width); //GPU上計算
63 timeEnd = clock();
64 ui.textEdit_GPU->setText(QString::number(timeEnd-timeStart)+"ms");
65
66 free(M);
67 free(N);
68 free(Pg);
69 }
70
71 void cudaInQt::OnButtonClicked_CPU()
72 {
73 float *M,*N,*Pc;
74 int Width=1024; //1024×1024矩陣乘法
75 M=(float*)malloc(sizeof(float)*Width*Width);
76 N=(float*)malloc(sizeof(float)*Width*Width);
77 Pc=(float*)malloc(sizeof(float)*Width*Width); //保存CPU計算結果
78
79 srand(0);
80
81 matgen(M,Width); //產生矩陣M
82 matgen(N,Width); //產生矩陣N
83
84 double timeStart,timeEnd; //定義時間,求時間差用
85 timeStart = clock();
86 MatrixMultiplication(M,N,Pc,Width); //CPU上計算
87 timeEnd = clock();
88 ui.textEdit_CPU->setText(QString::number(timeEnd-timeStart)+"ms");
89
90 free(M);
91 free(N);
92 free(Pc);
93 }
5.測試結果
測試時開了其他的應用程序,另外本機配置很戳,看看吧,使用CUDA進行加速甩了使用傳統方法幾條街呢
后注:代碼中有點問題,測試結果也不對,后來發現了,改過的結果見該文http://www.cnblogs.com/Romi/archive/2012/05/17/2506787.html