【发布时间】:2014-12-09 08:36:38
【问题描述】:
我正在尝试为我的应用程序找到线程和块的最佳值。因此我写了一个小套装来运行线程数、块大小和网格大小的可能组合。我正在处理的任务是不可并行化的,因此每个线程都在计算其独特的问题,并且需要对其独特的全局内存块进行读写访问。我还必须增加 cudaLimitStackSize 才能运行内核。 当我尝试计算一次可以运行的最大线程数时遇到了问题。我的改进方法(感谢 Robert Crovella)是
threads = (freememory*0.9)/memoryperthread
其中freememory 是从cudaMemGetInfo 获得的,memoryperthread 是一个线程的全局内存要求。即使我减少常数因子,我仍然会遇到“未指定的启动失败”,我无法调试,因为调试器失败并显示Error: Internal error reported by CUDA debugger API (error=1). The application cannot be further debugged.。根据设置,此错误
当我尝试不同的块大小时,我也遇到了问题。任何大于 512 个线程的块大小都会产生“请求启动的资源过多”。正如 Robert Crovella 所指出的,这可能是我的内核占用了许多寄存器(-Xptxas="-v" 报告的 63 个)的问题。由于块可以分布在多个 multiProcessorCount 中,因此我找不到任何会突然遇到块大小为 1024 的限制。
我的代码对于线程和块的小值运行良好,但我似乎无法计算我可以同时运行的最大数量。有什么方法可以正确计算这些,还是我需要根据经验进行计算?
我知道内存繁重的任务对于 CUDA 来说并不是最佳选择。
我的设备是具有 Compute Capability 2.0 的 GTX480。现在我坚持使用CUDA Driver Version = 6.5, CUDA Runtime Version = 5.0。
我确实使用-gencode arch=compute_20,code=sm_20 进行编译以实现计算能力。
更新:将运行时更新到 6.5 后,上述大部分问题都消失了。我将按原样保留这篇文章,因为我提到了我遇到的错误,人们在搜索他们的错误时可能会偶然发现它。为了解决大块大小的问题,我不得不减少每个线程的寄存器(-maxrregcount)。
【问题讨论】:
-
您知道 CUDA 6.5 附带的
cudaOccupancyMaxPotentialBlockSize()函数吗?附带说明一下,您是否注意到您的驱动程序和运行时版本不匹配? -
感谢您的评论。是的,我已经看到了,但我不确定它是否适用于我的情况,因为它没有全局内存使用选项。我知道不匹配,但我不是我正在使用的系统的主要管理员。
-
我不确定你的问题。我的理解是您必须处理大量数据并且您遇到的问题是您没有足够的线程来实现线程和数据之间的一对一对应。当然,您的整体
thread数量不能超过2^31-1。如果totalmemory/memoryperthread > 2^31-1则必须增加每个线程处理的内存量。此外,您说“从此计算块大小”,但没有说如何。 -
通常,每个块的线程数是一个独立变量,您可以随意修复,对于 GTX480,提供的线程数少于
1024。通常会调整此变量以优化您的代码的性能。 -
感谢您的意见,我会相应地更新我的问题。