对于模糊的标题感到抱歉。
我写了一个内核来做一些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毫秒。这或多或少是典型的吗?我真的不明白我怎么能更快地做到这一点。特斯拉的工作会更快吗?快多少?
谢谢。
答案 0 :(得分:2)
不,GPU的执行计算能力不受限制。
如果没有看到实际代码,很难确定。对于您提供的示例,唯一明显错误的是1.0 / x部分。 “1.0”是双精度的,NVIDIA GPU的双精度浮点性能远低于单精度。此外,它甚至不应该在您的GTS 240上编译,因为它是计算能力1.1并且它根本没有双精度支持。
无论如何,您看到的性能几乎肯定是由于全局内存瓶颈造成的。 200系列没有很好的缓存功能,你必须采取特殊措施来优化内存访问。 (对于较新的GPU,这部分适用,但程度较小。)您需要了解代码的内存访问模式,并最大限度地减少全局内存访问。
答案 1 :(得分:0)
GPU上有一个内存层次结构。您希望确保您的内存访问尽可能快,因为您的IO带宽似乎是瓶颈。
您可能需要查看纹理内存以改善空间局部性和缓存。
答案 2 :(得分:0)
作为@tskuzzy发布的内存图的替代方案,我从Nsight剖析器中获取了这个。它展示了Fermi上的内存架构概述,包括哪些内存空间支持每种类型的指令(最靠近内核的行)。
答案 3 :(得分:0)
GPU确实做得很好,有些事情非常糟糕。诀窍是写你的代码来利用他们做得好的事情,并尽可能少地做他们做得不好的事情。
我怀疑,但由于你没有提供任何代码,所以你的瓶颈与GPU进行计算的速度无关。它将是以下之一:
可能令人惊讶的是,它不太可能是内核,而是显示很多问题的主机代码,代码也很重要。