2012-02-23 56 views
3

当我运行分析器对我的代码,输出的部分是:CUDA异形占用率非常低;如何诊断?

Limiting Factor 
Achieved Occupancy: 0.02 (Theoretical Occupancy: 0.67) 
IPC: 1.00 (Maximum IPC: 4) 

达到0.02占用似乎可怕低。这可能是由于配置文件运行时丢失了.csv文件吗?它抱怨:

Program run #18 completed. 
Read profiler output file for context #0, run #1, Number of rows=6 
Error : Error in profiler data file '/.../temp_compute_profiler_1_0.csv' at line number 1. No column found 
Error in reading profiler output: 
Application : "/.../bin/python". 
Profiler data file '/.../temp_compute_profiler_2_0.csv' for application run 2 not found. 
Read profiler output file for context #0, run #4, Number of rows=6 

我的块是32 * 4 * 1,网格为25 * 100,并且测试已经显示32个寄存器提供最佳性能(即使在溢出的结果)。

如果0.02号码是正确的,我怎么能去调试这是怎么回事?我已经尝试过移动可能的候选人,以共享和/或常量内存,与launch_bounds实验,数据移动到纹理等

编辑:如果从运行配置文件更多的数据会有所帮助,只是让我知道我可以提供它。谢谢阅读。

编辑2:请求的数据。

IPC: 1.00 
Maximum IPC: 4 
Divergent branches(%): 6.44 
Control flow divergence(%): 96.88 
Replayed Instructions(%): -0.00 
Global memory replay(%): 10.27 
Local memory replays(%): 5.45 
Shared bank conflict replay(%): 0.00 
Shared memory bank conflict per shared memory instruction(%): 0.00 

L1 cache read throughput(GB/s): 197.17 
L1 cache global hit ratio (%): 51.23 
Texture cache memory throughput(GB/s): 0.00 
Texture cache hit rate(%): 0.00 
L2 cache texture memory read throughput(GB/s): 0.00 
L2 cache global memory read throughput(GB/s): 9.80 
L2 cache global memory write throughput(GB/s): 6.80 
L2 cache global memory throughput(GB/s): 16.60 
Local memory bus traffic(%): 206.07 
Peak global memory throughput(GB/s): 128.26 

The following derived statistic(s) cannot be computed as required counters are not available: 
Kernel requested global memory read throughput(GB/s) 
Kernel requested global memory write throughput(GB/s) 
Global memory excess load(%) 
Global memory excess store(%) 
Achieved global memory read throughput(GB/s) 
Achieved global memory write throughput(GB/s) 

解决方案(S):

缺少数据是由于过低的超时值问题;某些数据的早期运行将超时并且数据不会被写入(并且这些错误消息将在稍后运行的垃圾邮件中丢失)。

达到0.02的占用率是由于达到maxint(2 ** 32-1)的active_warpsactive_cycles(以及潜在的其他值)造成的。减少分析脚本输入的大小会导致更多理智的值出现(包括更好/更实际的IPC和分支统计信息)。

+0

看看读/写数据花了多少时间,以及一些内核代码来看看发生了什么会很有趣。不知道丢失的csv文件,如果他们可能是一个问题。编辑:分析器的其他有趣的输出将是分支分支和未合并和合并内存读取/写入。 – martiert 2012-02-23 08:33:21

+0

这是您要查找的数据吗?这些价值对我来说似乎不合理;当然不喜欢0.02占用的东西。 – 2012-02-23 09:53:56

+1

为了使全局读写吞吐量的计数器不可用,有点奇怪,但会有所帮助。你可以给一些内核代码吗?我不知道你的内核是干什么的,或者它涉及多少工作。我认为你没有太多的数据,所以如果算法不涉及很多工作,对GPU来说可能会很少。 – martiert 2012-02-23 10:08:32

回答

3

Visual Profiler,Parallel Nsight和CUDA命令行分析器使用的硬件计数器是32位计数器,并会在2^32/shaderclock秒(〜5s)内溢出。一些计数器会比这更快溢出。如果您看到MAX_INT的值,或者您的持续时间以秒为单位,那么您可能会在工具中看到不正确的结果。

我建议将你的内核启动分成两个或两个以上启动进行性能分析,以便启动的持续时间小于1-2秒。在你的情况下,你的理论占有率为67%(32经/ SM),并且块大小为4经线。在划分工作时,您需要确保每个SM完全加载并且最好能够接收多个块。对于每次启动尝试启动NumSM * MaxBlocksPerSM * 10块。例如,如果您的GTX560拥有8个SM,并且您报告的配置高于您,则会将2500个块的单次启动分为640个640 640和640个4个发射。

改进的处理溢出支持应该是在未来的工具版本中。

+0

感谢您的更新/澄清。很高兴知道约5秒的规则。 :)我已经将其转换为接受的答案。 – 2012-02-24 04:08:30

0

这似乎是(一个大的一部分)您的问题在这里:

Control flow divergence(%): 96.88

这听起来像时96.88%的线程没有运行在同一时间同一指令。当变形中的每个线程同时运行相同的指令时,GPU才能真正并行运行线程。像if-else陈述事情可能会导致一个给定的经的一些线程进入if,和某些线程进入else,造成分歧。接下来会发生什么情况是GPU在执行每组线程之间来回切换,导致每个执行周期的占用率都不尽如人意。

为了改善这一点,尽量确保将一起在经执行线程(32同时在所有NVIDIA显卡今天......我认为)将全部通过内核代码走上相同的道路。有时对输入数据进行排序,以便类似的数据一起处理。除此之外,在内核代码的战略位置添加屏障可以提供帮助。如果经线的线程被迫偏离,屏障将确保在它们再次到达共同代码后,等待对方到达那里,然后以完全占用(对于该经线)继续执行。请注意,所有线程都必须阻止,否则会导致死锁。

我不能保证这是你的全部答案,但它似乎是在给你的问题列出的数字为代码的一个大问题。

+0

是的。看起来没错。另一个技巧是允许所有线程执行相同的指令,即使你真的不需要。如果线程不需要刚刚计算的数据,则可以将其丢弃。主要的是:如果可能的话避免分支(如果你不能,那么你的问题可能更适合CPU) – martiert 2012-02-23 13:56:50

+1

这可能是一个性能问题,但它与占用问题无关,除非像Greg指出的那样大部分的经纱比一根长长的经纱要早得多。 – harrism 2012-02-24 01:33:14

3

理论占有率是您可以在SM上执行的最大经纱数量除以设备限制。根据内核使用每块的线程,每个线程的寄存器或每块的共享内存,理论占用率可低于设备限制。

实现的入住率是衡量(active_warps/active_cyles)/max_warps_per_sm

实现的.02占用意味着SM上只有1根经线处于激活状态。给定10000 warp(2500块* 128线程/ WARP_SIZE)的启动,只有当你有极其不同的代码时,才会发生这种情况,除了1个立即退出并且1个warp运行很长时间以外,此外,实现占用率达到1时IPC的可能性非常小,因此我怀疑所报告的值存在错误。

如果你想帮助诊断问题,我建议你

  1. 发表您的设备信息
  2. 验证您推出<<<{25,100,1}, {128, 4, 1}>>>
  3. 发布您的代码

如果您不能发表你的代码我会建议捕获计数器active_cycles和active_warps并计算实现的占用率为

(active_warps/active_cycles)/48 

鉴于您的分析器日志中存在错误,可能导致结果无效。

我相信从输出你使用的是旧的Visual Profiler版本。您可能需要考虑更新到版本4.1,这既改进了PM计数器的收集,也有助于提供有关如何改进代码的提示。

+0

active_warps和active_cycles对我来说都是4294967295,AKA 2 ** 32-1。看起来我打maxint。 :/ 1.0/48〜= 0.02一旦我得到完整的详细资料,我会接受。谢谢! – 2012-02-24 01:12:37

+0

为了确保您对这些工具有很好的使用经验,如果您可以试用4.1版本并且让我们知道结果是否更好,那将是非常好的! – harrism 2012-02-24 01:33:42

+0

我们没有计划在开普勒之前触摸CUDA设置。 :/会有一个CUDA更新与开普勒一致吗?如果是这样,是否还有时间进行修改? (我假定这艘船已经航行了,但也许不是;) – 2012-02-24 04:07:42