2013-04-05 70 views
0

这里存储数据性能低是我的问题,以加快我的项目,我要保存的内部内核生成到共享内存的值,但是,我发现它需要这么长时间来保存该值。如果我删除“THIS LINE”(见下面的代码),即去掉“THIS LINE”,速度非常快,以保存值(100次加速!)。CUDA,在共享memroy

extern __shared__ int sh_try[]; 

__global__ void xxxKernel (...) 
{ 
    float v, e0, e1; 
    float t; 
    int count(0); 
    for (...) 
    { 
    v = fetchTexture(); 
    e0 = fetchTexture(); 
    e1 = fetchTexture(); 
    t = someDeviceFunction(v, e0, e1); 
    if (t>0.0 && t < 1.0) <========== <THIS LINE> 
     count++; 
    } 
    sh_try[threadIdx.x] = count; 
} 

main() 
{ 
    sth.. 
    START TIMING: 

    xxxKernel<<<gridDim.x, BlockDim.x, BlockDim.x*sizeof(int)>>> (...); 

    cudaDeviceSynchronize(); 

    END TIMING. 
    sth... 
} 

为了解决这个问题,我简化了我的代码,只是将数据保存到共享内存中。并停下来。因为我知道共享内存。是最有效的成员。除了注册,我不知道这个高延迟是正常还是我做错了。请给我一些建议!谢谢你们提前!

trudi

更新: 如果我替换共享全球MEM内存,它需要几乎在同一时间,为33ms无“THIS LINE”,它297ms。将数据保存到全局mem是否正常?需要与共享内存相同的时间?这也是“编译器优化”的一部分吗?

我也检查了其他类似的问题,也就是说,即将数据保存到共享内存或没有,这可能是由编译器优化造成的巨大时间差距,因为它是没有意义的计算数据,但不保存它们,所以编译器只是'删除'那些毫无意义的代码。

我不知道我是否共享相同的原因,因为行改变了游戏规则是一个假设 - “THIS LINE”,当我评论它,变量“计数”增加每次迭代,当我取消它在t有意义时增加。

任何想法?请...

+2

当更改单行代码时看到像这样的大速度差异时,很可能是因为编译器能够优化出大块代码。由于您的内核仅将数据存储在共享内存中,因此它没有任何用处。编译器可以检测到这一点,并用一个空内核来替代它。您可以通过使用'nvcc -ptx mycode.cu'查看代码输出来查看这两种情况的区别。 – 2013-04-05 07:48:13

+1

使用“@name”通知评论者。 ptx文件在某种程度上是可读的。要检查的主要问题是你的函数的主体。它应该以'.entry _Z6xxxKernelILi2EEvPj(){'开始。之后,汇编代码如下所示。 – stuhlo 2013-04-05 09:40:48

+0

@stuhlo,谢谢你的回复。也许我应该先弄清楚如何用nvcc -ptx编译。我得到一个错误'无法找到cutil_inline.h'任何想法? – trudiQ 2013-04-05 13:13:45

回答

1

通常情况下,当大的性能变化被看作是比较小的代码更改(如添加或删除一行代码在内核)的结果,性能变化不是由于实际性能的影响该行代码,但都是由于编译器做出不同的优化决策,这可能会导致批发添加或在你的内核的机器代码的缺失。

一个相对简单的方法来帮助确认这是看生成的机器代码。例如,如果所生成的机器代码的大小显着改变由于源代码的单个行的添加或缺失,也可能是编译器作出极大地影响该代码的优化决定的情况。

虽然它不是机器代码,但为了达到这些目的,合理的代理是查看生成的PTX代码,这是编译器创建的中间代码。

可以产生通过简单地将-ptx切换到您的编译命令PTX:

nvcc -ptx mycode.cu 

这将生成一个名为mycode.ptx您可以检查这些文件。当然,如果你的常规编译命令需要额外的开关(例如-I/path/to/include/files),那么这个命令可能需要那些相同的开关。 nvccmanual提供了有关代码生成选项的更多信息,并且有一个PTX manual可帮助您了解PTX,但您可能仅基于生成的PTX的大小就能得出一个大概的想法(例如,.ptx文件中的行数)。