CUDA笔记
nvidia-smi 命令使用
nvidiasmi -q:查询GPU详细信息;
nvidia-smi -q -l 0:查询特定GPU详细信息;
nvidia-smi -q -l 0 -d MEMORY:显示GPU特定信息;
nvidia-smi -h:英伟达的帮助命令。
Cuda 程序
CUDA 核函数
注意事项:
1、核函数在 GPU 上进行并行执行;
2、注意:
(1) 核函数必须有 gloabl 进行修饰,限定词 global 修饰;
(2)返回值必须是 void;
3、形式:
(1)global void kernel_function(argument arg)
{
printf(“Hello World from the GPU! \n”);// gpu 的输出只能使用 printf 函数
}
(2)void global kernel_function(argument arg)
{
printf(“Hello World from the GPU! \n”);// gpu 的输出只能使用 printf 函数
}
核函数不同于其他函数的注意事项:
- 核函数只能访问 GPU 内存;(不能访问 CPU 内存 (host),只能访问 GPU 内存 (device))
- 核函数不能使用变长参数;(需要明确参数的个数)
- 核函数不能使用静态变量;
- 核函数不能使用函数指针;
- 核函数具有异步性(由于 cpu 和 gpu 之间是异构的,所以 cpu 不会了解 gpu 线程是否执行完毕,需要显示的调用同步函数)。
CUDA 程序编写流程:
int main(void){主机代码;核函数调用;主机代码;return 0;}
注意:核函数不支持 C++ 的 iostream。
cuda 代码:
// 文件命名后缀 **.cu
# include <stdio.h>
__global__ void hello_from_gpu()
{printf("Hello World from the GPU! \n");
}int main(void)
{hello_from_gpu<<<4, 4>>>(); // 第一个指的是线程块 blocks(x, y, z),第二个指的是每个线程块threads(x, y, z)cudaDeviceSynchronize();return 0;
}
CUDA 线程模型
线程模型结构:
- 线程模型的重要概念:
(1)grid:网格; (2)block 线程块。 - 线程分块是逻辑上的划分,物理上线程部分块;
- 配置线程 <<<grid_size, block_size>>>
- 最大允许线程块大小:1024
最大允许网格大小:2^31 - 1 (针对一维网格)
一维的线程模型
- 每个线程在核函数中都有唯一的身份标识;
- 每个线程的唯一标识由这两个<<< grid_size, block_size>>>确定;grid_size,block_size 保存在内建变量(build-in varibale), 目前考虑的是唯一的情况:
(1)gridDim.x:该变量的数值等于执行配置中变量grid_size的值;
(2)blockDim.x:该变量的数值等于执行配置文件中变量 block_size 的值。 - 线程索引保存成内建变量(build-in variable):
(1)blockIdx.x:该变量指定一个线程在一个网格中的线程块索引值,范围是0 ~ gridDim.x - 1;
(2)threadIdx.x:该变量指定一个线程在一个线程块中的线程索引值,范围是0 ~ blockDim.x - 1;
代码:
# include <stdio.h>__global__ void hello_from_gpu(){const int bid = blockIdx.x;const int tid = threadIdx.x;const int id = threadIdx.x + blockIdx.x * blockDim.xprintf(" Hello Wordl from block %d and thread %d, global id %d! \n", blockIdx.x, threadIdx.x, id);}int main(void){hello_from_gpu<<<4, 4>>>();cudaDeviceSynchrinize();}
推广到多维线程
1、CUDA 可以组织三维的网格和线程块;
2、blockIdx 和 threadIdx 是类型为 uint3 的变量,该类型是一个结构体,具有(x, y, z)三个成员:
blockIdx.x; blockIdx.y; blockIdx.z
threadIdx.x; threadIdx.y; threadIdx.z
注意:内建变量只在核函数中有用,且无需定义!
定义多维网格和线程块
dim3 grid_size(Gx, Gy, Gz);
dim3 block_size(Bx, By, Bz);
多维网格和线程块的限制条件
- 网格大小限制:
gridDim.x 最大值: 2^31 - 1;
gridDim.y 最大值: 2^31 - 1;
gridDim.z 最大值: 2^16 - 1; - 线程块大小的限制:
blockDim.x 最大值:1024;
blockDim.y 最大值:1024;
blockDim.z 最大值:64;
注意:线程总数不能超过1024;