CUDA的计算能力1.0比3.5更快

3
我有一个CUDA程序在680gtx上运行,在测试不同的编译器选项时,我注意到以下情况:
  • 为计算能力1.0和sm 1.0编译我的代码会导致47毫秒的运行时间
  • 为计算能力3.5(也是2.0)和sm 3.0编译我的代码会导致60毫秒的运行时间

这样的结果可能有哪些原因?
我在Linux上使用Nsight编译器和CUDA 5.0进行编译,我的内核主要受制于内存。
谢谢。
命令如下:
cc 1.0
nvcc --compile -O0 -Xptxas -v -gencode arch=compute_10,code=compute_10 -gencode arch=compute_10,code=sm_10 -keep -keep-dir /tmp/debug -lineinfo -pg -v  -x cu -o  "BenOlaCuda/src/main.o" "../BenOlaCuda/src/main.cu"

cc 3.0

nvcc -lineinfo -pg -O0 -v -keep -keep-dir /tmp/debug -Xptxas -v -gencode arch=compute_30,code=sm_30 -gencode arch=compute_35,code=sm_35 -odir "BenOlaCuda/src" -M -o "BenOlaCuda/src/main.d" "../BenOlaCuda/src/main.cu"

关于编译我的内核的更多信息:

cc 1.0

ptxas info    : Compiling entry function '_Z15optimizePixelZ3tfPfS_S_S_tttttt' for 'sm_10'
ptxas info    : Used 40 registers, 68 bytes smem, 64 bytes cmem[1], 68 bytes lmem

cc 3.0

ptxas info    : Compiling entry function '_Z15optimizePixelZ3tfPfS_S_S_tttttt' for 'sm_30'
ptxas info    : Function properties for _Z15optimizePixelZ3tfPfS_S_S_tttttt
128 bytes stack frame, 100 bytes spill stores, 108 bytes spill loads
ptxas info    : Used 63 registers, 380 bytes cmem[0], 20 bytes cmem[2]

除了“sm 1.0”与“sm 3.5”的问题之外,最好避免这样溢出堆栈帧。也许可以减少一些循环展开或类似的操作? - solvingPuzzles
3个回答

6

大约两年前,我将我的模拟从CUDA3.2切换到CUDA4.0,发现性能下降了约10%。随着计算能力2.0的推出,nVidia引入了IEEE754-2008符合的浮点计算(CC 1.0使用IEEE754-1985)。这是性能下降的原因之一,另一个原因是取消了“向零舍入”。尝试使用编译器标志--use_fast_math编译您的CC 3.0可执行文件。这将启用CC 1.0的旧精度。


1
谢谢!这似乎解决了问题,现在两个内核的性能相当。 事实上,当增加块大小时,为cc3.0编译确实比预期快约5% :) - BenMatok
CC 1.0 中的“flush to zero”是什么? - user1197918
@Jeb11:看这里 https://dev59.com/_HI95IYBdhLWcg3w8iv1 - Michael Haidl

3
请注意,680无法运行SM 3.5代码 - 只能运行3.0。只有Titan可以运行SM 3.5。
我对您所看到的差异有两种完全不同的解释:
1.实际上没有执行GPU代码。如果您编译“GPU” 1.0(而不是“PTX”),可能会发生这种情况。请确保检查所有CUDA RT调用的错误值。
2.在某些相当罕见的情况下,编译为PTX 1.0的代码在被JIT转换为3.0后运行速度更快,然后直接编译为3.0的代码。这是由于用于发出GPU / PTX 1.0代码和SM 2+代码的不同编译器引起的。请注意,在大多数情况下,由2+编译器发出的代码更快 - 但据报道对于某些代码模式相反。
更新
显然,您的代码需要很多寄存器,并且为3.0分配更多寄存器(因为该架构具有更高的寄存器数量),从而限制了占用率。
您可以尝试更改块大小和/或限制代码使用的寄存器数量。在没有看到您的代码并使用分析器进行实验的情况下,很难提出任何建议。我还建议您在CUDA toolkit 5.5可用时尝试它 - 编译器可能会做出不同的权衡,从而提高代码的性能。

感谢回复, (0)编译器表示支持cc 3.5,但cc 2.x也会出现这种情况。 (1)计算结果相同,没有错误。 (2)性能差异似乎相当大,希望能提供更多有关此问题的信息 :) - BenMatok
1
什么是编译器?编译器总是允许您编译3.5版本的代码-无论您的系统中是否有Titan或K20。如果您指的是Nsihgt UI,则可能选择了与您的设备兼容的PTX 1.0版本。 - Eugene
1
回复:2 - 我确实同意30%的性能下降似乎有些太大了,因此我怀疑您根本没有执行GPU代码。您能粘贴Make输出以查看发出的编译器命令吗? - Eugene
你是正确的,编译器似乎正在编译为cc 3.0,但对于任何cc 2.x及以上版本仍存在问题。 我已更新原帖以包括make命令。 - BenMatok

0

我也曾经遇到过同样的问题。

显然,CUDA计算能力指数(1.0 2.0 2.1 3.0 3.5等)是衡量CUDA卡处理能力类型的一个指标。(参见:http://en.wikipedia.org/wiki/CUDA版本特性和规格,红色和绿色表格部分)。

另外,每张CUDA卡的计算能力也不同,这取决于GPU数量、类型和内存速度等因素。

所以,可能会有一张“仅”支持CUDA 3.0的卡,例如GTX-760,拥有1152个核心和CUDA 3.0,而另一张卡GT 640则只有384个核心,但支持CUDA 3.5)

唯一可以在两个设备上进行比较的代码必须是3.0兼容的,并且很可能在GTX 760上运行得更快,尽管它只支持3.0,而640支持3.5。

我认为他们应该更清楚地表明,计算能力指数并不是大多数人认为的速度问题,而是关于能力的问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接