CUDA GPU编程指南:一个简单的Hello world

2023年7月26日 2241点热度 1人点赞 0条评论

前言

这篇博文会介绍如何使用CUDA 在屏幕上打出Hello World!

直接上代码

#include <stdio.h>
#include <cuda_runtime.h>

__host__ void cpuSayHello() {
    printf("CPU: hello world!\n");
}

__device__ int getThreadID() {
    return threadIdx.x;
}

__global__ void sayHello() {
    printf("GPU: hello world!\n");
    printf("GPU thread ID : %d \n", getThreadID());
}

int main()
{
    sayHello<<<1, 3 >>> ();
    cpuSayHello();
    cudaDeviceSynchronize();
    return 0;
}

​ 运行结果:

CUDA01

​ 这个代码和纯C/C++代码有所不同,主要在于函数的调用方式,和在定义函数时在前面加了 host global device 三个关键字。

关键字 host global device

​ 这三个关键字用于定义函数的类型。

  1. global 修饰的函数,被定义为核函数,可以在普通函数类使用特殊方法调用,调用之后函数会在GPU上运行,需要注意的是,核函数的返回值必须是void。
  2. device 修饰的函数,表示可以在GPU中调用的函数,只能在核函数或者被device 修饰的函数中被调用,这种函数可以有返回值。
  3. host 修饰的函数为普通函数,和C/C++的函数性质一样,这个关键字是默认的,如果在.cu文件中函数定义时没有使用关键字修饰,那么默认就是host。

核函数的调用方式

​ 核函数的调用方式,与普通函数不同,调用格式为:

​ FunctionName<<<blockSize,threadSize>>>(par);

​ FunctionName: 函数名

​ blockSize: 线程块的数量

​ threadSIze: 线程数量

​ par:函数参数,可以有多个

同步

​ 从运行结果的输出顺序可知,核函数先被调用,而先输出是 “CPU:hello world!” ,调用核函数只是将计算任务扔给GPU,并不会等到所有的核函数中的代码执行完成再继续往下执行。所以再调用完核函数之后,可以根据自己需求,是否要等待同步。

​ 等待同步的函数为:

​ cudaDeviceSynchronize()

​ 这个函数会阻塞线程,直到GPU上的任务执行完成后。

大脸猫

这个人虽然很勤快,但什么也没有留下!

文章评论