1

我已经对块和线程的几个值进行了经验测试,使用特定值可以大大减少执行时间。

我看不出块和线程之间有什么区别。我认为可能是块中的线程具有特定的缓存内存,但对我来说这很模糊。目前,我将我的函数并行化为 N 个部分,这些部分分配在块/线程上。

我的目标可能是根据我必须使用的内存大小自动调整块和线程的数量。有可能吗?谢谢你。

4

3 回答 3

1

我相信自动调整块和线程大小是一个非常困难的问题。如果这很容易,CUDA 很可能会为您提供此功能。

原因是最佳配置取决于实现和您正在实现的算法类型。它需要分析和试验以获得最佳性能。

以下是您可以考虑的一些限制。

在内核中注册使用情况。占用您当前的实施。

注意:拥有更多线程并不等同于最佳性能。通过在您的应用程序中获得正确的占用率并让 GPU 内核始终保持忙碌状态,可以获得最佳性能。

于 2012-07-24T02:51:21.393 回答
1

到目前为止,洪舟的回答很好。以下是更多细节:

在使用共享内存时,您可能需要首先考虑它,因为它是一种非常有限的资源,并且内核不太可能有非常特定的需求来限制那些控制并行性的许多变量。您要么有许多线程共享较大区域的块,要么有较少线程共享较小区域的块(在不断占用的情况下)。

如果您的代码可以使用每个多处理器低至 16KB 的共享内存,您可能希望选择更大的 (48KB) L1 缓存调用

cudaDeviceSetCacheConfig(cudaFuncCachePreferL1);

此外,可以使用编译器选项为非本地全局访问禁用 L1 缓存,-Xptxas=-dlcm=cg以避免内核仔细访问全局内存时造成污染。

在担心基于占用率的最佳性能之前,您可能还想检查是否为 CUDA >= 4.1 关闭了设备调试支持(或给出了适当的优化选项,请阅读我在此线程中的帖子以获取合适的编译器配置)。

现在我们有了内存配置,并且寄存器实际上被积极使用,我们可以分析不同占用率下的性能:

占用率越高(每个多处理器的扭曲),多处理器必须等待的可能性就越小(用于内存事务或数据依赖),但更多的线程必须共享相同的 L1 缓存、共享内存区域和寄存器文件(参见 CUDA 优化指南和本演示文稿)。

ABI 可以为可变数量的寄存器生成代码(更多细节可以在我引用的线程中找到)。然而,在某些时候,会发生寄存器溢出。也就是说,寄存器值会临时存储在(相对较慢的、片外的)本地内存堆栈上。

在分析器中观察停顿原因、内存统计信息和算术吞吐量,同时改变启动边界和参数将帮助您找到合适的配置。

理论上可以从应用程序中找到最佳值,但是,让客户端代码针对不同的设备和启动参数进行最佳调整可能很重要,并且需要重新编译或为每个目标设备架构部署不同的内核变体。

于 2012-08-30T13:32:03.410 回答
0

我在这里有一个很好的答案,总之,这是一个计算块和线程上的最佳分布的难题。

于 2012-07-21T13:17:44.603 回答