GPU在进行更大规模计算方面的能力有限吗?

时间:2012-06-08 19:58:45

标签: performance parallel-processing cuda hardware gpu

对于模糊的标题感到抱歉。

我写了一个内核来做一些3D热传递的模拟。我遇到的问题是我在8核Dell Studio XPS上并行运行的程序版本超过了我的GTS-240 GPU。我已经尝试了许多尝试让它运行得更快的东西,但我得出结论,只是计算本身太大了。计算大约有35个FLOP,我只是为模拟中的每个单元格启动一个线程。尽管如此,我在GPU上只获得了大约3340万个单元/秒,在CPU上只有40.4毫安/秒。据我所知,GPU擅长这样的任务,每个时间步长有170万个单元,每个单元都需要对它们进行计算。

每次计算我也有28个数组访问,全部都在普通的GPU内存中。

这是计算。我不会发布真实的东西 - 不是它的绝密,它只是不必要的。前缀为“f”的变量是浮点数,“i”表示整数。

f_celldata[iA] =(-f_constA[iA-iB] * (f_mutA[iA] - f_mutA[iA-iB]) / f_constB[iA-1] + 
                  f_constA[iA]    * (f_mutA[iA+iB] - f_mutA[iA]) / f_constB[iA]) * (1.0 / f_constB[iA]) + 
                 (-f_constA[iA-iC] * (f_mutA[iA] - f_mutA[iA-iC]) / f_constB[iA-1] + 
                   f_mutA[iA] * (f_constA[iA+*iC] - kern_T_mat[linOffset]) / kern_dy_e[y]) * (1.0  /kern_dy_c[y]) + 
                  (-f_constA[iA-1] * (f_mutA[iA] - f_mutA[iA-1]) / f_constB[iA-1] + 
                    f_constA[iA] * (f_mutA[iA+1] - f_mutA[iA]) / f_constB[iA]) * (1.0 / f_constB[iA]);

当我在这里写下来时,显然我有点草率。实际上,计算尽可能简单,而且还有很多变量,在这里,我为了简单起见做了同样的事情。

我希望人们对GPU编程更有经验,而不是给我一些建议。计算是否太大而无法使用GPU?单独的单个计算(数组访问和FLOP一起)每个时间步长需要35毫秒。这或多或少是典型的吗?我真的不明白我怎么能更快地做到这一点。特斯拉的工作会更快吗?快多少?

谢谢。

4 个答案:

答案 0 :(得分:2)

不,GPU的执行计算能力不受限制。

如果没有看到实际代码,很难确定。对于您提供的示例,唯一明显错误的是1.0 / x部分。 “1.0”是双精度的,NVIDIA GPU的双精度浮点性能远低于单精度。此外,它甚至不应该在您的GTS 240上编译,因为它是计算能力1.1并且它根本没有双精度支持。

无论如何,您看到的性能几乎肯定是由于全局内存瓶颈造成的。 200系列没有很好的缓存功能,你必须采取特殊措施来优化内存访问。 (对于较新的GPU,这部分适用,但程度较小。)您需要了解代码的内存访问模式,并最大限度地减少全局内存访问。

答案 1 :(得分:0)

GPU上有一个内存层次结构。您希望确保您的内存访问尽可能快,因为您的IO带宽似乎是瓶颈。

您可能需要查看纹理内存以改善空间局部性和缓存。

enter image description here

答案 2 :(得分:0)

Fermi Memory Architecture

作为@tskuzzy发布的内存图的替代方案,我从Nsight剖析器中获取了这个。它展示了Fermi上的内存架构概述,包括哪些内存空间支持每种类型的指令(最靠近内核的行)。

答案 3 :(得分:0)

GPU确实做得很好,有些事情非常糟糕。诀窍是写你的代码来利用他们做得好的事情,并尽可能少地做他们做得不好的事情。

我怀疑,但由于你没有提供任何代码,所以你的瓶颈与GPU进行计算的速度无关。它将是以下之一:

  • 您花费大部分时间将数据移入/移出GPU。
    • 即。你的内核很简单,几乎没有时间执行,但是加载源数据并获得结果需要时间。
    • GPU喜欢在单个数据集上做很多工作。
  • 您正在使GPU与CPU同步工作,并且您的CPU受限制。
    • 如果你有一个CPU循环等待GPU完成,准备下一组工作,然后再次启动GPU,很容易在CPU上瓶颈。最好利用GPU正在为GPU准备下一组工作的时间,而不是仅仅等待。
  • 你不是要求足够的并行线程来完成这项工作。
    • GPU很快,因为它可以运行数百个线程。不是因为一个线程很快(它不是)。
    • 如果你无法利用这一点,那就毫无意义了。
  • 您正在使用慢速内存来存储变量。
    • GPU具有各种具有各种访问速度的内存类型。小,本地和快速;大,全球但很慢。
    • 经常访问的变量希望尽可能快地存储。

可能令人惊讶的是,它不太可能是内核,而是显示很多问题的主机代码,代码也很重要。