CUDA C简介
目标
- 编写第一段CUDA C代码;
- 了解主机(HOST)编写代码与为设备端编写代码之间的区别;
- 了解如何从主机端运行设备代码
- 了解如何在支持CUDA的设备上使用设备内存
- 了解如何查询系统中支持CUDA的设备信息
第一个程序
Hello,World!
#include <stdio.h>
int main(void)
{
printf("Hello, World!\n");
return 0;
}
编译这个例子
nvcc main.cu -o edit
这里就完成了一个简单的Hello Word,这个例子只是表明CUDA C与熟悉的C语言完全相同,这个例子能够独立的在主机端运行。
这里我们将CPU和系统内存称为主机(HOST),将GPU及其内存称为设备(DEVICE)。这个例子应为没有考虑到主机之外的设备,所以和以前的代码几乎完全相同。下面将描述如何使用GPU这一设备来执行代码。在GPU上执行的代码通常称为核函数(Kernel)。
核函数的调用
#include <stdio.h>
__global__ void kernel(void)
{
}
int main(void)
{
kernel<<<1,1>>>();
printf("Hello, World!\n");
return 0;
}
这个例子和前面相比,多了两个值得注意的地方:
- 一个空的核函数
kernel()
,并且带有修饰符__global__
- 以及对这个核函数的调用,并且带有修饰字符
<<<1,1>>>
同时应为代码是交给系统标准的C编译器来编译的,如Linux是使用gcc
来编译主机代码,win下是使用VC来编译主机代码。NVIDIA工具只是将代码交给主机编译工具。上面的例子中可以看到CUDA C为标准C增加了__global__
修饰符。这个修饰符告诉编译器,函数应该在设备上而不是主机端运行。在上面的例子中函数kernel()
被交给编译设备代码的编译器,被交给主机编译器。函数被交给主机编译器。
从前面我们可以看到CUDA需要通过一种特殊的语法将一个函数标记为“设备代码(Device Code)”。这并没有什么特别的地方,只是一种简单的表示方式,表示将主机代码发送到一个编译器,而将设备代码发送到另一个编译器。事实上,这里的关键在于如何在主机代码中调用设备代码。这里CUDA编译器和运行时负责实现从主机代码中调用设备代码。
所以可以知道<<<1,1>>kernel()
表示调用设备代码,<<<n,m>>>
表示要将一些参数传递给运行时的系统,这些参数并不是传递给设备代码的参数而是描述如何启动设备代码。
传递参数
#include <stdio.h>
_