【问题标题】:Massive performance loss when writing data写入数据时性能损失巨大
【发布时间】:2012-05-15 00:10:01
【问题描述】:

我在代码中对 float* 内存块进行了一些计算。由于我正在处理图像,因此我必须使用宽度 * 高度点和 180 次旋转来执行此操作。我正在启动 180 个线程(每度旋转 1 个),因为这是代码中唯一可并行化的过程。 我旋转图像,并为每次旋转获取每个点的结果浮点值。 我有另一个 float* 块,它存储每个点的当前最大值。

if(resultMap[i] < convrst)
{
    resultMap[i] = convrst;
    rMap[i] = (unsigned char)r0;
    oMap[i] = (unsigned char)index;
}

使用 resultMap 存储当前的最大值。 convrst 是卷积的结果,如果当前结果高于之前的结果,则保存该值,加上该点的半径(r0)和旋转(索引)。 r0 最初是一个 int,以及索引。 i 是一个从 0 到 imgsize-1 的计数器

如果没有 { } 部分中的分配,整个代码将在 2 秒内完成,而分配则需要 50 秒(这还没有考虑到我在该代码中省略了锁以避免同步问题) .

为什么这段代码这么慢,我该怎么做才能让它更快完成?

【问题讨论】:

  • 你在什么 GPU 上运行它?
  • 这是一台配备 Core i5-2410M 和 GeForce GT 540M 的笔记本电脑
  • 你运行内核的块有多少? 180 个线程是要使用的很小(并且是错误的)线程数,即使对于像 GT 540M 这样的 2 SM GPU 也是如此

标签: cuda


【解决方案1】:

当您在内核中包含写入时,速度大幅下降的原因与this question 中的相同(尽管它与 OpenCL 相关,但原理相同)。 NVIDIA 编译器非常积极地优化掉“死”代码,即对共享内存或全局内存写入没有贡献的代码。所以我猜当你不包括对全局内存的写入时,如你的问题所示,编译器只是在优化大量内核,大大减少了执行时间。

因此,正如我链接的另一个问题一样,真正的问题应该是为什么您的内核需要 50 秒才能完成。这将需要有关代码和调用它的执行参数的更多信息,但如果如您所写,您只运行 180 个线程,那可能是罪魁祸首。 GPU 需要更多的并行度才能实现峰值性能。

【讨论】:

  • 谢谢你,我怀疑当我忽略对内存的写入时它忽略了计算昂贵的部分(尽管我尝试从项目属性中关闭优化)。我做什么:以 1 度的步长将图像旋转 180 度,并计算旋转图像的卷积。由于每个卷积都需要完整的图像,我想不出其他方法来获得更多的并发线程。如果我做块而不是线程有帮助吗?目前,GPU 和 CPU 都需要大约 50 秒来完成该任务,而且 CPU 版本根本没有线程化......
猜你喜欢
  • 2013-11-04
  • 2014-09-17
  • 1970-01-01
  • 2015-01-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多