与第三方CUDA库链接会降低cudaMalloc的速度

与第三方CUDA库链接会降低cudaMalloc的速度,cuda,gpgpu,gpu,Cuda,Gpgpu,Gpu,在CUDA 4.x上第一次调用cudamaloc 速度可能慢得离谱(这已经被报道了好几次),这似乎是CUDA驱动程序中的一个bug 最近,我注意到了奇怪的行为:cudamaloc 直接取决于我链接到我的程序的第三方CUDA库的数量 (请注意,我不使用这些库,只是将我的程序与它们链接起来) 我使用以下程序运行了一些测试: int main() { cudaSetDevice(0); unsigned int *ptr = 0; cudaMalloc((void **)&ptr,

在CUDA 4.x上第一次调用
cudamaloc
速度可能慢得离谱(这已经被报道了好几次),这似乎是CUDA驱动程序中的一个bug

最近,我注意到了奇怪的行为:
cudamaloc
直接取决于我链接到我的程序的第三方CUDA库的数量 (请注意,我不使用这些库,只是将我的程序与它们链接起来)

我使用以下程序运行了一些测试:

int main() {
  cudaSetDevice(0);
  unsigned int *ptr = 0;
  cudaMalloc((void **)&ptr, 2000000 * sizeof(unsigned int));   
  cudaFree(ptr);
return 1;
}
结果如下:

  • 链接至:-lcudart-lnpp-lcufft-lcublas-lcusparse-lcurand 运行时间:5.852449

  • 链接到:-lcudart-lnpp-lcufft-lcublas运行时间:1.425120

  • 链接至:-lcudart-lnpp-lcufft运行时间:0.905424

  • 链接至:-lcudart运行时间:0.394558

根据“gdb”,时间确实进入了我的Cudamaloc,所以它不是由某些原因造成的 库初始化例程


我想知道是否有人对此有合理的解释?

在您的示例中,
cudamaloc
调用在GPU上启动惰性上下文建立。当包含运行时API库时,必须检查它们的二进制有效负载,并将它们包含的GPU elf符号和对象合并到上下文中。库的数量越多,您可以期望该过程花费的时间就越长。此外,如果任何一个cubins中存在架构不匹配,并且您拥有向后兼容的GPU,那么它还可以触发驱动程序重新编译目标GPU的设备代码。在一个非常极端的情况下,我看到一个与CUBLAS旧版本链接的旧应用程序在费米GPU上运行时需要10秒的时间来加载和初始化

您可以通过如下方式发出
cudaFree
调用显式强制惰性上下文建立:

int main() {
    cudaSetDevice(0);
    cudaFree(0); // context establishment happens here
    unsigned int *ptr = 0;
    cudaMalloc((void **)&ptr, 2000000 * sizeof(unsigned int));   
    cudaFree(ptr);
  return 1;
}

如果您使用计时器配置或插入此版本,您会发现第一个
cudaFree
调用占用了大部分运行时,
cudamaloc
调用几乎免费。

谢谢@talomines,实际上在开始时插入cudaFree需要整个运行时间。我最初在GT650M图形卡(开普勒核心)上测试了这个程序,而在费米GPU GTX580上,它需要更长的时间——大约7秒。。NVIDIA仍然可以使用smth来优化其上下文管理—7秒的完整CPU工作负载似乎太难了much@asm:试试CUDA 5,看看它能做什么。现在工具链中有了一个合适的设备代码链接器,所以运行时的一些开销可能会转移到编译和链接时(或者至少简化一点)。此外,如果您发现这回答了您的问题,您可以接受它,以便将您的问题标记为已回答。请注意,在CUDA 4.0中,CUDA初始化花费这么长时间的部分原因是因为驱动程序正在为统一虚拟寻址执行大量虚拟内存分配。还请注意,驱动程序将JIT编译的内核缓存在磁盘上。如果您更改了硬件,它必须重新进行工作,但就内核编译而言,第二次应该比第一次快得多。