我正在开发应该在具有不同内存和计算能力的几个CUDA GPU上运行的软件。我不止一次地想到客户会在GPU上报告一个我无法在我的机器上重现的可重现问题。也许是因为我有8 GB的GPU内存并且它们有4 GB,可能是因为计算能力3.0而不是2.0,这样的事情。
因此问题是:我可以暂时降级"降级"我的GPU会假装是一个较小的型号,内存较少和/或计算能力较低?
每条评论都澄清了我的要求。
假设客户报告在GPU上运行的问题,其计算能力为C
,其中GPU内存为M
,每个块为T
个线程。我的机器上有更好的GPU,具有更高的计算能力,更多的内存和更多的每个块的线程。
1)我可以在GPU上运行我的程序,仅限{1}} GPU内存吗?这个问题的答案似乎是"是的,只是在启动时分配(无论你有什么记忆) - M
并且从不使用它;在您的程序退出之前,只会留下M
。"
2)在运行时间内,我可以将GPU上的块大小减少到不超过M
个线程吗?
3)我是否可以在运行期间降低GPU的计算能力,如我的程序所示?
答案 0 :(得分:3)
我原本想把它作为评论,但它对于那个范围来说太大了。
正如@RobertCrovella所提到的那样,没有本地方式可以满足您的要求。也就是说,您可以采取以下措施来最小化您在其他架构上看到的错误。
0)尝试从您想要定位的CUDA GPU获取cudaGetDeviceProperties
的输出。您可以从您的用户或社区群众中获取此信息。
1)要限制内存,您可以实现内存管理器并手动跟踪正在使用的内存,也可以使用cudaGetMemInfo
获得相当接近的估计值。注意:此函数也返回其他应用程序使用的内存。
2)使用包装器宏来启动内核,您可以在其中显式检查块/线程的数量是否适合当前配置文件。即取代发射
kernel<float><<<blocks, threads>>>(a, b, c);
你会做这样的事情:
LAUNCH_KERNEL((kernel<float>), blocks, threads, a, b, c);
您可以在此处定义宏:
#define LAUNCH_KERNEL(kernel, blocks, threads, ...)\
check_blocks(blocks);\
check_threads(threads);\
kernel<<<blocks, threads>>>(__VA_ARGS__)
3)无法降低计算能力,但是您可以使用各种计算模式编译您的代码,并确保您的内核中包含向后兼容的代码。如果你的内核的某个部分错误地使用较旧的计算模式,你可以这样做:
#if !defined(TEST_FALLBACK) && __CUDA_ARCH__ >= 300 // Or any other newer compute
// Implement using new fancy feature
#else
// Implement a fallback version
#endif
只要您想测试后备代码并确保代码适用于较旧的计算,就可以定义TEST_FALLBACK
。