从一个简单的例子进入cuda的学习:
cpp
#include <stdio.h>
#include <cuda.h>
#include <cuda_runtime.h>
__global__ void hello_cuda(){
// 泛指当前线程在所有block范围内的全局id
unsigned int idx = blockIdx.x * blockDim.x + threadIdx.x;
printf("block id = [ %d ], thread id = [ %d ] hello cuda\n", blockIdx.x, idx);
}
int main() {
hello_cuda<<< 3, 4 >>>();
cudaDeviceSynchronize();
return 0;
}
// 输出
// block id = [ 2 ], thread id = [ 8 ] hello cuda
// block id = [ 2 ], thread id = [ 9 ] hello cuda
// block id = [ 2 ], thread id = [ 10 ] hello cuda
// block id = [ 2 ], thread id = [ 11 ] hello cuda
// block id = [ 1 ], thread id = [ 4 ] hello cuda
// block id = [ 1 ], thread id = [ 5 ] hello cuda
// block id = [ 1 ], thread id = [ 6 ] hello cuda
// block id = [ 1 ], thread id = [ 7 ] hello cuda
// block id = [ 0 ], thread id = [ 0 ] hello cuda
// block id = [ 0 ], thread id = [ 1 ] hello cuda
// block id = [ 0 ], thread id = [ 2 ] hello cuda
// block id = [ 0 ], thread id = [ 3 ] hello cuda
(1)idx -- 线程的id
(2)global 表示cuda kernel 函数的前缀,该函数被cpu调用启动,在gpu上执行
(3)blockDim.x和blockIdx.x 表示block内线程的数量以及每个block的id
(4)threadIdx.x表示block内的线程id
(5)<<< 3 , 4 >>> 在main函数中启动cuda kernel函数的标志,第一个参数表示block的数量,第二个参数表示每个block内的线程数量
(6)cudaDeviceSynchronize()表示该函数强制cpu等待gpu上的cuda kernel执行,即同步,这里也可以不写,只是cpu比gpu先执行完
host : cpu端部调用且在cpu端部执行的函数,正常的c++代码,无任何修饰符时默认是cpu端函数
device: GPU端调用且在GPU端执行的函数,可以理解为GPU端的函数封装,且编译器确定是否inline
noinline:强制编译器不inline
forceinline:强制编译器inline
eg:
host devce int run_on_cpu_or_gpu(){
return 1;
}
block中有很多个线程,
CUDA函数有哪些函数组成
1)__global__修饰的CUDA Kernel函数
2)main函数,基于<<<... , ... >>>启动cuda Kernel函数
3)可选::__device__和__host__修饰的函数