1.申请内存 2.转移拷贝 3.释放空间 4.核函数2.头文件
- 关于cuda操作的一些接口都在这个头文件里
#include3.申请内存
cudaMalloc()接口
| 参数 | 含义 |
|---|---|
| void *p | 内存地址的指针 |
| size_t s | 申请的内存大小 |
| cudaError_t | 返回类型 |
cudaError_t cudaMalloc(void **p, size_t s)4.转移拷贝
cudaMemcpy()接口
| 参数 | 含义 |
|---|---|
| void *dst | 目标设备指针 |
| const void *src | 源设备指针 |
| size_t count | 内存复制的字节大小 |
| cudaMemcpyKind | 含义 |
|---|---|
| cudaMemcpyHostToDevice | CPU–>GPU |
| cudaMemcpyDeviceToHost | GPU–>CPU |
cudaError_t cudaMemcpy(void *dst, const void *src, size_t count, enum cudaMemcpyKind kind);5.释放空间
cudaFree接口
cudaError_t cudaFree(void *devPtr);6.核函数
1.定义
- __global__标志核函数,在host调用,在device上执行
- 核函数的返回类型必须是void
- threadIdx线程索引 thread index
- blockDim线程块维度
- blockIdx线程块索引 block index
__global__
void vecAddKernel(float* A_d, float* B_d, float* C_d, int n)
{
// GPU中执行并行计算的thread id
// 类比CPU中计算数组位置
int i = threadIdx.x + blockDim.x * blockIdx.x;
if (i < n) C_d[i] = A_d[i] + B_d[i];
}
2.调用
- <<< >>> 告诉运行时如何启动设备(调用几个block,调用几个线程)
vecAddKernel <<< blockPerGrid, threadPerBlock >>> (da, db, dc, n);7.编译与运行
使用nvcc进行编译
# 命令行终端执行 nvcc my_gpu_add.cu -o my_gpu_add
生成可执行文件my_gpu_add
运行
# 参数为执行加法运算的次数,相当于数组的大小 ./my_gpu_add 18.源代码
附上源代码
// my_gpu_add.cu #include#include #include // 核函数 __global__ void vectorAddKernel(float * A_d, float * B_d, float * C_d, int n){ int i = threadIdx.x + blockDim.x * blockIdx.x; if(i <= n) C_d[i] = A_d[i] + B_d[i]; } int main(int argc, char * argv[]){ int n = atoi(argv[1]); std::cout << "执行加法" << n << "次" << std::endl; // 要申请的内存大小 size_t size = n * sizeof(float); // 先在host上申请内存,生成数据 // 在CPU上使用 free - malloc 申请内存方式 float *a = (float*)malloc(size); float *b = (float*)malloc(size); float *c = (float*)malloc(size); // 生成随机数组 for(int i = 0; i < n; i++){ float af = rand() / double(RAND_MAX); float bf = rand() / double(RAND_MAX); a[i] = af; b[i] = bf; } // 定义device指针 float * da = NULL; float * db = NULL; float * dc = NULL; // 显存申请 cudaMalloc((void **) &da, size); cudaMalloc((void **) &db, size); cudaMalloc((void **) &dc, size); // 转移拷贝 host --> device cudaMemcpy(da, a, size, cudaMemcpyHostToDevice); cudaMemcpy(db, b, size, cudaMemcpyHostToDevice); cudaMemcpy(dc, c, size, cudaMemcpyHostToDevice); // 调用核函数 vectorAddKernel<<< n/256+1, 256>>> (da, db, dc, n); std::cout<<"nblockPerGrid:"< host cudaMemcpy(c, dc, size, cudaMemcpyDeviceToHost); // 释放显存 cudaFree(da); cudaFree(db); cudaFree(dc); // std::cout<<"a:"<<*a<<"n"; // std::cout<<"b:"<<*b<<"n"; // std::cout<<"c:"<<*c<<"n"; // 释放空间 free(a); free(b); free(c); return 0; }



