CUDA C++ 编程指引:编程模型 | CUDA
本文最后更新于:2022年6月23日
可扩展的编程模型使得已编译好的 CUDA 程序能够在任意核心的 GPU 上执行。
内核函数
下面这段代码通过语法 <<<...>>>
指定使用 N 个线程去执行 VecAdd
函数,每个执行内核函数的线程拥有一个独一无二的线程 ID,可以通过内置的 threadIdx 变量在内核函数中访问。限定符 __global__
声明某函数为内核函数,在设备上执行,只能从主机端调用。
__global__ void VecAdd(float* A, float* B, float* C) {
int i = threadIdx.x; C[i] = A[i] + B[i];
}
int main() {
...
VecAdd<<<1, N>>>(A, B, C);
...
}
线程
下面这段代码指定使用 1 个含有 N*N 个 线程(二维网格形状)的线程块执行 MatAdd
函数。另外,一个块内的线程数目是有限的,在目前的 GPU 中,一个线程块最多有 1024 个线程。
__global__ void MatAdd(float A[N][N], float B[N][N], float C[N][N]) {
int i = threadIdx.x;
int j = threadIdx.y;
C[i][j] = A[i][j] + B[i][j];
}
int main() {
...
int numBlocks = 1;
dim3 threadsPerBlock(N, N);
MatAdd<<<numBlocks, threadsPerBlock>>>(A, B, C);
...
}
一个内核函数可被多个同样大小的线程块执行。下面这段代码指定使用 N/threadsPerBlock.x*N/threadsPerBlock.y 个含有 16*16 个线程的线程块执行 MatAdd
函数。
__global__ void MatAdd(float A[N][N], float B[N][N], float C[N][N]) {
int i = blockIdx.x * blockDim.x + threadIdx.x;
int j = blockIdx.y * blockDim.y + threadIdx.y;
if (i < N && j < N)
C[i][j] = A[i][j] + B[i][j];
}
int main() {
...
dim3 threadsPerBlock(16, 16);
dim3 numBlocks(N / threadsPerBlock.x, N / threadsPerBlock.y);
MatAdd<<<numBlocks, threadsPerBlock>>>(A, B, C);
...
}
参考
CUDA C++ Programming Guide
《CUDA C Programming Guide》(《CUDA C 编程指南》)导读
《CUDA 并行程序设计:GPU 编程指南》
评论系统采用 utterances ,加载有延迟,请稍等片刻。