cuda基础

函数

cudaMallocHost
1
2
3
cudaError_t cudaMallocHost(void ** devPtr,size_t count);
//float *buf;
//cudaMallocHost((void **)&buf,bytes);

分配主机上的固定内存

host内存:分为pageable memory 和 pinned memory

pageable memory: 通过操作系统API(malloc(),new())分配的存储器空间;

pinned memory:始终存在于物理内存中,不会被分配到低速的虚拟内存中,能够通过DMA加速与设备端进行通信;

使用Malloc分配的内存都是Pageable(交换页)的,而另一个模式就是Pinned(Page-locked),实质是强制让系统在物理内存中完成内存申请和释放的工作,不参与页交换,从而提高系统效率,需要使用cudaHostAlloc和cudaFreeHost(cudaMallocHost的内存也这样释放)来分配和释放。

cudaMalloc
1
2
3
cudaError_t cudaMalloc(void** devPtr, size_t size);
//float *d_buf;
//cudaMalloc((void **)&d_buf,bytes);

分配设备内存

cudaMemcpy
1
2
cudaError_t CUDARTAPI cudaMemcpy(void *dst, const void *src, size_t count, enum cudaMemcpyKind kind);
// cudaMemcpy(d_buf,buf,bytes,cudaMemcpyHostToDevice);
__syncthreads()

syncthreads()将确保线程块中的每个线程都执行完 syncthreads()前面的语句后,才会执行下一条语句.

声明符

__global__

修饰的是核函数,运行在GPU上,返回值必须是void,且不能被放到class里面。需要声明运行时的block_num和block_size.

1
bodyForce<<<block_num,block_size>>>(d_p, dt, nBodies); 
__device__

代表在device上运行的function,而且它们只能从device调用。这个声明不能和__global__ 同时使用

__host__

同样地,”host“声明的函数只能在host上面运行,而且只能从host调用。如果一个函数没有使用上面三种声明符的任何一种,那么默认会被认为是”host“函数。跟”device“一样,”host“也不能跟”global“同时使用。

线程配置

1
kernel<<<Dg,Db,Ns,S>>>(param list);
  • Dg:int类型或者dim3类型,用来定义一个Grid中Block时如何组织的。
  • Db:int类型或者dim3类型, 用来定义Block中Thread是如何组织的。
  • Ns:可缺省,默认为0。用来设置每个block除了静态分配的共享内存外,最多动态分配的共享内存大小,单位是byte。
  • S:cudaStream_t类型,可缺省,默认为0,表示核函数在哪个流。
1
kernel_name<<<5,8>>>(...);

表示一个grid有5个block,(x,y,z)上排布为(5,1,1)。一个block有8个Thread,排布为(8,1,1);

在CUDA上可以使用内置变量来获取Thread ID和Block ID:

  • threadIdx.[x, y, z]表示Block内Thread的编号
  • blockIdx.[x, y, z]表示Gird内Block的编号
  • blockDim.[x, y, z]`表示Block的维度,也就是Block中每个方向上的Thread的数目
  • gridDim.[x, y, z]表示Gird的维度,也就是Grid中每个方向上Block的数目

ref

  1. CUDA — cudaMalloc / cudaMallocHost - 手磨咖啡 - 博客园 (cnblogs.com)

  2. cuda 函数前缀 host device global __noinlineforceinline 简介-CSDN博客

  3. CUDA编程(4.1)—— 声明符 - 知乎 (zhihu.com)

  4. GPU编程2—CUDA核函数和线程配置 - 知乎 (zhihu.com)