我已经根据经验测试了块和线程的几个值,并且可以使用特定值大大减少执行时间。
我没有看到块和线程之间有什么区别。我认为可能是块中的线程具有特定的高速缓存,但对我来说它非常模糊。目前,我将我的函数并行化为N个部分,这些部分分配在块/线程上。
我的目标可能是自动调整块数和线程数量与我要使用的内存大小有关。有可能吗?谢谢。
答案 0 :(得分:1)
我相信自动调整块和线程大小是一个非常困难的问题。如果这很容易,CUDA很可能会为您提供此功能。
原因是最佳配置取决于实现和您正在实现的算法类型。它需要进行分析和实验才能获得最佳性能。
您可以考虑以下一些限制。
在内核中注册使用情况。 您当前实施的占用情况。
注意:拥有更多线程并不等同于最佳性能。通过在应用程序中获得正确的占用率并始终保持GPU核心处于忙碌状态,可以获得最佳性能。
答案 1 :(得分:1)
使用共享内存时,您可能需要先考虑它,因为它是一个非常有限的资源,并且内核不太可能有非常具体的需求限制 控制并行性的那些变量。 您要么拥有许多线程共享较大区域的块,要么具有较少的块 共享较小区域的线程(在恒定占用率下)。
如果您的代码每个多处理器只能使用16KB的共享内存 您可能希望选择更大的(48KB)L1缓存调用
cudaDeviceSetCacheConfig(cudaFuncCachePreferL1);
此外,可以使用编译器选项-Xptxas=-dlcm=cg
禁用L1高速缓存以进行非本地全局访问,以避免在内核仔细访问全局内存时造成污染。
在担心基于入住率的最佳表现之前,您可能还需要检查 为CUDA> = 4.1关闭了设备调试支持(或者给出了适当的优化选项,请在this thread中阅读我的帖子以获得合适的编译器 配置)。
现在我们有一个内存配置和寄存器实际上是积极使用的, 我们可以分析不同占用情况下的表现:
占用率(每个多处理器的warp)越高,多处理器必须等待的可能性越小(对于内存事务或数据依赖性),但是线程必须共享相同的L1高速缓存,共享内存区域和寄存器文件(参见CUDA优化)指南以及this presentation)。
ABI可以为可变数量的寄存器生成代码(更多细节可以在我引用的主题中找到)。但是,在某些时候,会发生寄存器溢出。也就是说,寄存器值暂时存储在(相对较慢的片外)本地存储器堆栈中。
在分析器中查看停顿原因,内存统计信息和算术吞吐量 改变启动边界和参数将帮助您找到合适的配置。
理论上可以从应用程序中找到最佳值,但是, 使客户端代码最佳地调整到不同的设备和启动参数 可能是非常重要的,需要重新编译或为每个目标设备架构部署内核的不同变体。
答案 2 :(得分:0)
我的答案非常好here,总之,计算块和线程的最佳分布是一个难题。