GPU程序一般有哪些步骤
1.CPU分配空间给GPU(cudaMalloc)
2.CPU复制数据给GPU
3.CPU加载kernels给GPU做计算
4.CPU把GPU计算结果复制过来。
过程中,一般要尽量降低数据通讯的消耗,所以如果程序需要大量的数据到GPU,显然不是很合适使用GPU运算,最理想的情况是,每次复制的数据很小,然后运算量很大,然后输出的结果很小,然后复制回CPU。
例程:
#include<stdio.h>
__global__ void square(float* d_out, float* d_in){ //__gloabal__表示这一段程序我们是在GPU上运行的
int idx = threadIdx, x;
float f = d_in[idx];
d_out[idx] = f*f;
}
第一步:CPU分配空间给GPU(cudaMalloc)
```c
int main(int argc, char** argv){
const int ARRAY_SIZE = 64; //数组的size是64, int定义的量是变量,它的值可以更改;而const int定义的是一个常量,它的值不可以更改。
const int ARRAY_BYTES = ARRAY_SIZE * sizeof(float);
//generate the input array on the host
float h_in[ARRAY_SIZE]; //表示插在CPU上的变量
//declare GPU memory pointers
float* d_in; //以d_开头的代表这是插在GPU上的
float* d_out; //以d_开头的代表这是插在GPU上的memory
// allocate GPU memory
cudaMalloc((void**) &d_in, ARRAY_BYTES); //在GPU上分配空间
cudaMalloc((void**) &d_out, ARRAY_BYTES);
// transfer the array to GPU
cudaMemcpy(d_in, h_in, ARRAY_BYTES, cudaMemcpyHostToDevice); // 第二个参数是原位置,第一个参数是目标位置,最后一个参数表示方向,HostToDevice。
//launch the kernel
//CPU加载kernels给GPU做计算
square<<<1, ARRAY_SIZE>>>(d_out, d_in); //第一个参数1表示加载在多少个线程块上面,第二个表示每个线程块上要多少个线程,每个线程都运行square的代码,就这段代码而言,这是代表一个线程块,每个线程块有64个线程。
//现在的话看不到输出,因为一直都是在GPU上操作的,现在我们需要把结果带回给CPU。
//copy back the result array to the GPU
cudaMemcpy(h_out, d_out, ARRAY_BYTES,cudaMemCpyDeviceToHost);
// print out the resulting array
for(int i=0;i<ARRAY_SIZE;i++){
print("%f",h_out[i]);
print()
}
// free GPU memory allocation
//最后把内存释放掉
cudaFree(d_in);
cudaFree(d_out);
return 0;
}