在并行环境中,任务可以是任意操作。例如,应用程序可以执行两个任务:其中一个线程重绘程序的GUI,而另一个线程通过网络下载更新包。这些任务并行执行,彼此之间没有任何共同的地方。虽然GPU上的任务并行性并不像CPU上的任务并行性那样灵活,但仍然可以进一步提高程序在GPU上的运行速度。本章将介绍CUDA流,以及如何通过流在GPU上同时执行多个任务。 页锁定(Page-Locked)主机内存 CUDA提供了自己独有的机制来分配主机内存:cudaHostAlloc()。malloc()分配的内存与cudaHostAlloc()分配的内存之间存在一个重要差异。C库函数malloc()将分配标准的、可分页的(Pagable)主机内存,...

在某些情况中,对于单线程应用程序来说非常简单的任务,在大规模并行架构上实现时会变成一个复杂的问题。在本章中,我们将举例其中一些情况,并在这些情况中安全地完成传统单线程应用程序中的简单任务。 原子操作简介 在编写传统的单线程应用程序时,程序员通常不需要使用原子操作。下面会介绍一下原子操作是什么,以及为什么在多线程程序中需要使用它们。我们先分析C或者C++的递增运算符: x++; 在这个操作中包含了三个步骤: 读取x中的值。 将步骤1中读到的值增加1。 将递增后的结果写回到x。 有时候,这个过程也称为读取-修改-写入操作。 当两个线程都需要对x的值进行递增时,假设x的初始值为7,理想情况下,两个线程按顺序对x进行递增,第一个线程完成三个...

本章将学习如何分配和使用纹理内存(texture memory)。和常量内存一样,纹理内存是另一种类型的只读内存,在特定的访问模式中,纹理内存同样能够提升性能并减少内存流量。虽然纹理内存最初是针对传统的图形处理应用程序而设计的,但在某些GPU计算应用程序中同样非常有用。 与常量内存相似的是,纹理内存同样缓存在芯片上,因此在某些情况中,它能够减少对内存请求并提供更高效的内存带宽。纹理缓存是专门为那些在内存访问模式中存在大量空间局部性(spatial locality)的图形应用程序而设计的。在某个计算应用程序中,这意味着一个线程读取的位置可能与邻近线程读取的位置“非常接近”。 热传导模拟 本章用一个简单的热传导模拟的模型来介绍如何使用...

这一章会介绍如何在CUDA C中使用常量内存、了解常量内存的性能特性以及学习如何使用CUDA事件来测量应用程序的性能。 常量内存 到目前为止,我们知道CUDA C程序中可以使用全局内存和共享内存。但是,CUDA C还支持另一种类型的内存,即常量内存。常量内存用于保存在核函数执行期间不会发生变化的数据。在某些情况下,用常量内存来替换全局内存能有效地减少内存带宽。 在GPU上实现光线跟踪 我们给出一个简单的光线跟踪应用程序示例来学习。由于OpenGL和DirectX等API都不是专门为了实现光线跟踪而设计的,因此我们必须使用CUDA C来实现基本的光线跟踪器。本示例构造的光线跟踪器非常简单,旨在学习常量内存的使用上(并不能通过示例代码来...

这一章将介绍线程块以及线程之间的通信机制和同步机制。 在GPU启动并行代码的实现方法是告诉CUDA运行时启动核函数的多个并行副本。我们将这些并行副本称为线程块(Block)。 CUDA运行时将把这些线程块分解为多个线程。当需要启动多个并行线程块时,只需将尖括号中的第一个参数由1改为想要启动的线程块数量。 在尖括号中,第二个参数表示CUDA运行时在每个线程块中创建的线程数量。假设尖括号中的变量为«<N, M»>总共启动的线程数量可以按照以下公式计算: $$ N个线程块 * M个线程/线程块 = N*M个并行线程 $$ 使用线程实现GPU上的矢量求和 在之前的代码中,我们才去的时调用N个线程块,每个线程块对应一个线程add<<<N,...

这一部分将介绍CUDA的并行编程方式 矢量求和运算 假设有两组数据,我们需要将这两组数据中对应的元素两两相加,并将结果保存在第三个数组中。 基于CPU的矢量求和 首先,下面的代码是通过传统的C代码来实现这个求和运算 #include "../common/book.h" #define N 10 void add(int *a, int *b, int *c){ int tid = 0; //这是第0个CPU,因此索引从0开始 while(tid < N){ c[tid] = a[tid] + b[tid]; tid += 1; //由于只有一个CPU,因此每次递增1 } } int main(){ int a[N], b[N],...

参考书目: GPU高性能编程CUDA实战 书目网页链接: https://hpc.pku.edu.cn/docs/20170829223652566150.pdf 该博客参考于上述书籍,虽然书有一点老,但是作为初学者而言仍然能学到很多东西。 本书所包含的代码都在下面的连接中,可以下载来学习: https://developer.nvidia.com/cuda-example CUDA C简介 首先来看一个CUDA C的示例: #include "../common/book.h" int main(){ prinf("Hello World!\n"); return 0; } 这个示例只是为了说明,CUDA C与熟悉的标准C在很大程...