GPU高性能编程CUDA实战-第3讲.pdf
文本预览下载声明
第 3 章
CUDA C简介
如果你学习了第1章的内容,那么我们认为你已经了解了图形处理器的
强大计算能力,并且需要在程序中使用这种能力。此外,如果你学习了第2
章的内容,那么就应该配置好了编译和运行CUDA C代码的开发环境。如
果你跳过了这两章的内容,例如只是想浏览代码示例,或者只是在书店里
随机地打开这本书翻到这页,或者可能迫不及待地想立即开始动手编写和
运行代码,那么也没关系。无论是何种情况,你都应该准备好了编写第一
个代码示例,那么让我们开始吧。
16 GPU高性能编程CUDA实战
3.1 本章目标
通过本章的学习,你可以:
• 编写第一段CUDA C代码。
• 了解为主机(Host )编写的代码与为设备(Device )编写的代码之间的区别。
• 如何从主机上运行设备代码。
• 了解如何在支持CUDA 的设备上使用设备内存。
• 了解如何查询系统中支持CUDA 的设备的信息。
3.2 第一个程序
我们希望通过示例来学习CUDA C ,因此来看第一个CUDA C示例。为了保持计算机编程
书籍的行文风格,我们首先给出的是一个“Hello, World! ”示例。
3.2.1 Hello, World!
#include ../common/book.h
int main( void ) {
printf( Hello, World!\n );
return 0;
}
当看到这段代码时,你肯定在怀疑本书是不是一个骗局。这不就是C 吗?CUDA C是不是
真的存在?这些问题的答案都是肯定的。当然,本书也不是一个骗局。这个简单的“Hello ,
World !”示例只是为了说明,CUDA C与你熟悉的标准C在很大程度上是没有区别的。
这个示例很简单,它能够完全在主机上运行。然而,这个示例引出了本书的一个重要区分:
我们将CPU 以及系统的内存称为主机,而将GPU及其内存称为设备。这个示例程序与你编写过
的代码非常相似,因为它并不考虑主机之外的任何计算设备。
为了避免使你产生一无所获的感觉,我们将逐渐完善这个简单示例。我们来看看如何使用
GPU (这就是一个设备)来执行代码。在GPU设备上执行的函数通常称为核函数(Kernel )。
3.2.2 核函数调用
现在,我们在示例程序中添加一些代码,这些代码比最初的“Hello ,World !”程序看上
去会陌生一些。
第3 章 CUDA C简介 17
#include iostream
_global_ void kernel( void ) {
}
int main( void ) {
kernel1,1();
printf( Hello, World!\n );
return 0;
}
这个程序与最初的“Hello ,World !”相比,多了两个值得注意的地方:
• 一个空的函数kernel() ,并且带有修饰符__global__ 。
• 对这个空函数的调用,并且带有修饰字符1,1 。
在上一节中看到,代码默认是由系统的标准C编译器来编译的。例如,在Linux操作系统上
用GNU gcc 来编译主机代码,而在Windows 系统上用Microsoft Visual C 来编译主机代码。
NVIDIA 工具只是将代码交给主机编译器,它表现出的行为就好像CUDA不存在一样。
现在,我们看到了CUDA C为标准C增加的__global__ 修饰符。这个修饰符将告诉编译器,
函数应该编译为在设备而不是主机上运行。在这个简单的示例中,函数kernel()将被交给编译设
备代码的编译器,而main() 函数将被交给主机编译器(与上一个例子一样)。
那么,kernel() 的调用究竟代表着什么含义,并且为什么必须加上尖括号和两个数值?注意,
这正是使用CUDA C 的地方。
我
显示全部