GPU通用可编程技术中的scatter与gather

来源:互联网 发布:新疆网络为什么这么差 编辑:程序博客网 时间:2024/05/22 22:21
<script type="text/javascript"><!--google_ad_client = "pub-0008935412623678";//728x90, created 1/16/08google_ad_slot = "8291575712";google_ad_width = 728;google_ad_height = 90;//--></script> <script type="text/javascript"src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>


随着GPU可编程性能的增强以及GPGPU技术的不断发展,人们希望基于流处理器模型的GPU能够像CPU一样,在支持流程分支的同时,也允许对存储器进行灵活的读写操作。在进行早期的GPU通用可编程技术研究时,Ian Buck [1]就曾经指出,缺乏灵活的存储器操作,是制约GPU完成复杂计算任务的关键,因此他在设计Brook [2]时增加了对scatter/gather特性的支持,但是其实现过程仍然是通过一些以牺牲性能为代价的技巧完成的。
    在
GPUscatter/gather的实现与第一向量机中的很相似,scatter允许将数据输出到非连续的存储器地址内,而gather则允许从非连续的存储器地址内读取数据。因此如果认为存储器(如DRAM)是一个二维数组,scatter可以看作利用下标将数据写入数组中的任意位置,即a[i] = x,而gather可以看作是利用下标从数组中的任意位置读出数据,即x = a[i]
    在
CUDA [5]的架构中(图1),每个ALU可以看作是一个处理核心,通过scatter/gather操作,多个ALU间可以共享存储器,实现对任意地址数据的读写操作。

图1:CUDA的scatter/gather

scatter/gather有什么用?

举个常见的排序例子,如果要我们对一个数组中的数据进行排序,最直接的想法就是用冒泡算法,即通过遍历数组找到其中最大的数,将它与队列中的第一个数据对调,然后将剩余数组中第二大的数与第二个数据对调,依次执行直到剩下数组的最后一项时排序结束。在这个过程中,两个数据项的对调,在存储器操作上,就可以通过对数组中的任意位置读取和写入数据来完成。

上面的例子在CPU上很容易实现,因为IAIntel Architecture)架构的处理器架构是支持scatter/gather操作的。但是在GPU上,由于存在vertex shaderfragment shader,以及流处理器模型对并行性的追求,情况变得有点复杂。

GPU中的scatter/gather实现

先说fragment shader,因为可以对纹理进行预取(fetch),并通过纹理坐标的调节获取纹理中的任意数据 [4],所以片段处理器实际上可以从存储器(显存)中的任意地址读取数据,也就是说能够实现gather操作。但是反过来看,fragment shader的输出只能指向特定的片段,而且必须是依据固定顺序排列的,因此fragment shader实际上并不能够实现scatter操作。

但是,利用多渲染对象(render to texture)以及多次渲染(multi-pass rendering)技术,可以将前一次渲染出的数据以纹理形式存储,并作为下一次渲染的输入,即通过从任意位置读取数据的方式来弥补无法向任意位置写入数据的缺陷。这样,只要规划好数据的索引(纹理坐标),是可以在多次渲染过程中实现伪scatter效果的。这也就是大家通常都感觉fragment shadervertex shader用起来灵活的原因,但这种灵活是以耗时的多次渲染和占用大量存储器空间为代价的。

再来看vertex shader,一般在对顶点流中的每个顶点进行处理时,只能够针对当前顶点的一些数据进行处理,而无法同时使用多个顶点的数据,这就意味着无法实现对存储器任意地址的数据进行读写操作,也就是不具备scatter/gather功能。

但是随着vertex texture技术的出现,vertex shader能够像fragment shader一样通过纹理采样的方式从纹理中获取数据,因此就具备了从存储器的任意位置读取数据的gather能力。

Geometry shader的出现以及vertex buffer技术的发展,为几何处理过程中实现scatter操作提供了可能。无论是DirectX10还是即将推出的OpenGL 3.0 [6],都提出了几何处理过程中需要具备数据反馈(feed-back)与多次操作(multi-pass)的能力(图2),这实际上已经让我们看到了几何处理阶段实现scatter的可能。

图2:DirectX 10 pipeline

结论

GPGPU领域中,存储器的灵活操作至关重要,随着图形处理器的发展,人们已经可以在处理流水线的各个阶段实现并行的的scatter/gather操作。但是考虑到图形处理器中的数据精度、存储器操作性能等因素,在目前阶段,GPU中的scatter/gather操作仍然存在很大局限,这一方面限制了GPGPU领域的发展,但同时也为图形处理器今后的发展指明了方向。

  参考文献

1.        Ian Buck, Pat Hanrahan, "Data Parallel Computation on Graphics Hardware"

2.        Ian Buck, Tim Foley, "Brook for GPUs: Stream Computing on Graphics Hardware"

3.        Ian Buck, “Stream Computing On Graphics Hardware”, Ph.D. 2004

4.        Timothy John Purcell, "Ray Tracing on a Stream Processor", 2004, p19

5.        Nvidia, “CUDA Programming Guide”, 2007

6.        Evan Hart, “New OpenGL Features”, 2006, GDC 2007

7.        Christophe, “OpenGL Vertex Buffer Objects”, 2006, http://www.ozone3d.net//tutorials//opengl_vbo_p1.php

<script type="text/javascript"><!--google_ad_client = "pub-0008935412623678";//728x90, created 1/16/08google_ad_slot = "8291575712";google_ad_width = 728;google_ad_height = 90;//--></script> <script type="text/javascript"src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>