当warp的所有线程读取相同的全局内存时会发生什么?

时间:2012-05-24 07:42:02

标签: cuda gpu gpgpu gpu-programming

我想知道当warp的所有线程读取相同的32位全局内存地址时发生了什么。有多少内存请求?有没有序列化。 GPU是Fermi卡,编程环境是CUDA 4.0。

此外,任何人都可以解释总线使用的概念吗?缓存加载和非缓存加载有什么区别?我在http://theinf2.informatik.uni-jena.de/theinf2_multimedia/Website_downloads/NVIDIA_Fermi_Perf_Jena_2011.pdf中看到了这个概念。

1 个答案:

答案 0 :(得分:3)

warp中的所有线程访问全局内存中的相同地址

对于AMD GPU,我可以回答您的问题。对于Nvidia,谷歌搜索得到了足够快的答案。

  

我想知道当warp的所有线程读取相同的32位全局内存地址时发生了什么。有多少内存请求   那里?有没有序列化。 GPU是费米卡   编程环境是CUDA 4.0。

2009年的

http://developer.download.nvidia.com/CUDA/training/NVIDIA_GPU_Computing_Webinars_Best_Practises_For_OpenCL_Programming.pdf说:

  

聚结:

     

全局内存延迟:400-600个周期。最重要的一点   性能考虑!

     

半warp线程的全局内存访问可以合并到   一个大小为8位,16位,32位,64位或2位字的事务   128位的交易。

     

全局记忆可以被视为组成16和16的对齐片段   32个字。

     

在计算能力1.0和1.1中合并:

     

半经线中的第K个线程必须访问段中的第k个字;   但是,并非所有线程都需要参与

     

在计算能力中合并
  1.2和1.3:

     

合并适合分段大小的任何访问模式

因此,听起来像使用warp访问的所有线程相同的32位全局内存地址都可以正常工作,在任何> = Compute Capability 1.2中。但不适用于1.0和1.1。

你的卡好吗。

我必须承认我没有为Nvidia测试过这个。我已经为AMD测试了它。


缓存和未缓存负载之间的差异

首先,请查看您引用的演示文稿的幻灯片4 http://theinf2.informatik.uni-jena.de/theinf2_multimedia/Website_downloads/NVIDIA_Fermi_Perf_Jena_2011.pdf

即。标题为" CPU与CPU之间差异的幻灯片的GPU" - 这说明CPU拥有巨大的缓存,而且GPU没有。

几年前,这样的幻灯片可能会说GPU根本没有任何缓存。但是,GPU已经开始添加越来越多的缓存,和/或越来越多的本地缓存。

我不确定你是否理解"缓存"在计算机体系结构中。这是一个很大的话题,所以我只会提供一个简短的答案。

基本上,缓存就像本地内存。缓存和本地存储器 - 比DRAM,主存储器更接近处理器或GPU - 无论是GPU的私有DRAM,还是CPU的系统存储器。 DRAM主存是由Nvidia Global Memory调用的。幻灯片9说明了这一点。

缓存和本地内存都比GPU全局内存更靠近GPU:在幻灯片9中,它们被绘制为与GPU在同一芯片内,而DRAM是单独的芯片。这可以产生几个好的效果,包括延迟,吞吐量,功耗,以及总线利用率(与带宽相关)。

延迟:全局内存距离为400-800个周期。这意味着如果您的应用程序中只有一个warp,它将每400-800个周期执行一次内存操作。这意味着,为了不减速,您需要许多线程/ warp产生可以并行运行的内存请求,即具有高MLP(内存级并行)的内存请求。幸运的是,图形通常会这样做。缓存更接近,因此具有更低的延迟。你的幻灯片没有说它是什么,但其他地方说50-200个周期,比全球记忆快4-8倍。这意味着需要更少的线程和扭曲以避免减速。

吞吐量/带宽:本地存储器和/或高速缓存通常比DRAM全局存储器带宽更多。你的幻灯片说1 + TB / s与177 GB / s相比 - 即缓存和本地内存的速度提高了5倍以上。这种更高的带宽可以转化为更高的帧速率。

电源:您可以节省大量电源到缓存或本地内存而不是DRAM全局内存。这对桌面游戏PC来说无关紧要,但对于笔记本电脑或平板电脑来说这很重要。实际上,它甚至对桌面游戏PC也很重要,因为较少的功率意味着它可以(更快)计时。

好的,所以本地和缓存内存在上面类似吗?有什么区别?

基本上,编程缓存比本地内存更容易。非常好,专家,nionja程序员需要正确管理本地内存,根据需要从全局内存中复制内容,并将其清除。缓存内存更容易管理,因为您只是执行缓存加载,内存自动放入缓存中,下次访问时可以更快地访问内存。

但是缓存也有缺点。

首先,它们实际上比局部存储器消耗更多的功率 - 或者如果实际存在单独的本地和全局存储器,它们会更多。但是,在Fermi中,本地存储器可以配置为高速缓存,反之亦然。 (多年来,GPU人员说,#34;我们不需要没有臭味缓存 - 缓存标签和其他开销是最浪费的。)

更重要的是,缓存倾向于在缓存行上运行 - 但并非所有程序都运行缓存。这会导致您提到的总线利用率问题。如果warp访问缓存行中的所有单词,那很好。但是,如果warp只访问高速缓存行中的1个字,即1个4字节字,然后跳过124个字节,则通过总线传输128个字节的数据,但只使用4个字节。即> 96%的总线带宽被浪费了。这是低总线利用率。

然而,下一张幻灯片显示非缓存加载(可能用于将数据加载到本地内存中)只会传输32个字节,因此"仅#34;浪费了32个中的28个字节。换句话说,非缓存负载可以比缓存负载高4倍,速度快4倍。

那为什么不在任何地方使用非缓存加载?因为它们更难编程 - 它需要专业的忍者程序员。缓存在很多时候都能很好地工作。

所以,不要让专业的忍者程序员花费大量时间来优化所有代码以使用非缓存加载和手动管理的本地内存 - 而是使用缓存加载来做简单的事情,然后你让高薪专家忍者程序员专注于缓存不能很好地工作的东西。

此外:没有人喜欢承认它,但通常缓存比专家忍者程序员更好。

希望这会有所帮助。 吞吐量,功率和总线利用率:除了减少