CUDA 为许多常用编程语言提供扩展,而在本实验中,我们将会为 C/C++ 提供扩展。这些语言扩展可让开发人员在 GPU 上轻松运行其源代码中的函数。
以下是一个 .cu
文件(.cu
是 CUDA 加速程序的文件扩展名)。其中包含两个函数,第一个函数将在 CPU 上运行,第二个将在 GPU 上运行。请抽点时间找出这两个函数在定义方式和调用方式上的差异。
void helloCPU()
{
printf("Hello from the CPU.\n");
}
__global__ void helloGPU()
{
printf("Hello also from the GPU.\n");
}
int main()
{
helloCPU();
helloGPU<<<1, 1>>>();
cudaDeviceSynchronize();
}
以下是一些需要特别注意的重要代码行,以及加速计算中使用的一些其他常用术语:
__global__ void GPUFunction()
__global__
关键字表明以下函数将在 GPU 上运行并可全局调用,而在此种情况下,则指由 CPU 或 GPU 调用。void
。使用 __global__
关键字定义的函数需要返回 void
类型。GPUFunction<<<1, 1>>>();
<<< ... >>>
语法完成的配置。1
线程(第二个配置参数)的 1
线程块(第一个执行配置参数)启动核函数。cudaDeviceSynchronize();
cudaDeviceSynchronize
将导致主机 (CPU) 代码暂作等待,直至设备 (GPU) 代码执行完成,才能在 CPU 上恢复执行。
```!nvcc -arch=sm_70 -o hello-gpu 01-hello/01-hello-gpu.cu -run
Hello from the CPU. Hello also from the GPU.
请进行以下修改,并尝试在每次更改后编译并运行该应用程序。若出现错误,请花时间仔细阅读错误内容:熟知错误内容会在您开始编写自己的加速代码时,给与很大的帮助。
__global__
。注意错误中的行号:您认为错误中的 \”configured\” 是什么意思?完成后,请替换 __global__
。A:
>>>
01-hello/01-hello-gpu.cu(29): error: a host function call cannot be configured
1 error detected in the compilation of "/tmp/tmpxft_0000009f_00000000-8_01-hello-gpu.cpp1.ii".
启动核函数时,我们必须提供执行配置, 但是删除global后的函数实际上是普通的host function,无法进行configure。
A:
>>>
01-hello/01-hello-gpu.cu(29): error: a __global__ function call must be configured
1 error detected in the compilation of "/tmp/tmpxft_000000a8_00000000-8_01-hello-gpu.cpp1.ii".
cudaDeviceSynchronize
的调用。在编译和运行代码之前,猜猜会发生什么情况,可以回顾一下核函数采取的是异步启动,且 cudaDeviceSynchronize
会使主机执行暂作等待,直至核函数执行完成后才会继续。完成后,请替换对 cudaDeviceSynchronize
的调用。A: 程序顺利执行完毕,但未输出GPU的函数的输出。
01-hello-gpu.cu
,以便 Hello from the GPU
在 Hello from the CPU
之前打印。#include <stdio.h>
void helloCPU()
{
printf("Hello from the CPU.\n");
}
__global__ void helloGPU()
{
printf("Hello also from the GPU.\n");
}
int main()
{
helloGPU<<<1, 1>>>();
cudaDeviceSynchronize();
helloCPU();
}
01-hello-gpu.cu
,以便 Hello from the GPU
打印两次,一次是在 Hello from the CPU
之前,另一次是在 Hello from the CPU
之后。#include <stdio.h>
void helloCPU()
{
printf("Hello from the CPU.\n");
}
__global__ void helloGPU()
{
printf("Hello also from the GPU.\n");
}
int main()
{
helloGPU<<<1, 1>>>();
cudaDeviceSynchronize();
helloCPU();
helloGPU<<<1, 1>>>();
cudaDeviceSynchronize();
}