好久没写东西了,晚上睡梦中突发想写点什么的欲望,干脆把最近看的cuda总结下吧。
下面是一个简单的小程序,实现普通的矩阵相加,当然乘法,转置等操作自然就可以照葫芦画瓢了。
// 这里添加头文件,当然业可以有诸如#include<somefile.cu>,我指的是在vc编译下,如果用nvcc,详见
/*************************************************************************************************/
// nvcc --help
nvcc.exe -ccbin "C:\Program Files\Microsoft Visual Studio 8\VC\bin" -c -DWIN32 -D_DEBUG -D_CONSOLE -Xcompiler "/EHsc /W3 /nologo /Wp64 /Od /Zi /RTC1 /MTd " -IC:\CUDA\include -o Debug\my_homework.obj my_homework.vcproj
Release:
"$(CUDA_BIN_PATH)\nvcc.exe" -ccbin "$(VCInstallDir)bin" -c -DWIN32 -D_CONSOLE -D_MBCS -Xcompiler /EHsc,/W3,/nologo,/Wp64,/O2,/Zi,/MT -I"$(CUDA_INC_PATH)" -I./ -I../../common/inc -o .\Release\$(InputName).obj .\libopenjpeg\$(InputName).cu
.\Release\$(InputName).obj
EmuDebug:
$(CUDA_BIN_PATH)\nvcc.exe -ccbin "$(VCInstallDir)bin" -deviceemu -c -D_DEBUG -DWIN32 -D_CONSOLE -D_MBCS -Xcompiler /EHsc,/W3,/nologo,/Wp64,/Od,/Zi,/RTC1,/MTd -I"$(CUDA_INC_PATH)" -I./ -I../../common/inc -o .\EmuDebug\$(InputName).obj .\libopenjpeg\$(InputName).cu
.\EmuDebug\$(InputName).obj
/*************************************************************************************************/
#include <stdio.h>
// __global__ 是所谓的kernel标志,它所修饰的函数run in device,calledable by host
//相应的有 __device__ , __host__ 以及每个修饰字符应用上的限制。
__global__ void testkernel(int *d_A,int*d_B,int*d_C, size_t d_size,size_t all_size)
{
int dx = blockDim.x * blockIdx.x + threadIdx.x;
int dy = blockDim.y * blockIdx.y + threadIdx.y;
/*实现矩阵相加,这段代码充分显示了 并行计算的优势,仅仅一行代码,表示了8×8矩阵的相加,当问题规模上升时,然运行速度也是相当可观的*/
/*********************************************************************************************************************/
如果是在cpu下运行的话,那么代码
for(int j=0;j<8;j++)
for(jj=0;jj<8;jj++)
h_B[j*rsize+jj]=h_A[j][jj]+h_AA[j][jj];
/*********************************************************************************************************************/
d_C[dx*d_size+dy]=d_A[dx*d_size+dy]+d_B[dx*d_size+dy];
}
int main( int argc, char** argv)
{
int h_A[8][8] = {{1,1,1,1,2,2,2,2},
{1,1,1,1,2,2,2,2},
{1,1,1,1,2,2,2,2},
{1,1,1,1,2,2,2,2},
{3,3,3,3,4,4,4,4},
{3,3,3,3,4,4,4,4},
{3,3,3,3,4,4,4,4},
{3,3,3,3,4,4,4,4}};
int h_AA[8][8] = {{1,1,1,1,2,2,2,2},
{1,1,1,1,2,2,2,2},
{1,1,1,1,2,2,2,2},
{1,1,1,1,2,2,2,2},
{3,3,3,3,4,4,4,4},
{3,3,3,3,4,4,4,4},
{3,3,3,3,4,4,4,4},
{3,3,3,3,4,4,4,4}};
int *d_A,*d_B,*d_C, *h_B;
//其中,size_t,dim3是cuda内置的变量类型,如dim3的默认值为(1,1,1)
size_t size = 8 * 8 * sizeof(int);
size_t rsize = 8;
dim3 dimgrid(2,2);
dim3 dimblock(4,4);
h_B = (int*)malloc(size);
//在显卡内存里初始化
cudaMalloc( (void **) &d_A, size );
cudaMalloc( (void **) &d_B, size );
cudaMalloc( (void **) &d_C, size );
//cuda内存从Host复制到Device
cudaMemcpy( d_A, h_A, size, cudaMemcpyHostToDevice );
cudaMemcpy( d_B, h_AA, size, cudaMemcpyHostToDevice );
//由host调用kernel,是device执行运算
testkernel<<<dimgrid,dimblock>>>(d_A,d_B,d_C,rsize,size-1);
cuda内存从Device复制到Host
cudaMemcpy( h_B, d_C, size, cudaMemcpyDeviceToHost );
for(int i = 0; i < 8; i++)
{
for(int j = 0;j < 8; j++)
printf("%2d ",h_B[i*rsize+j]);
printf("\n");
}
//清理显卡存储
cudaFree(d_A);
free(h_B);
}