C++:升级到 GTX970 后 cv::gpu::GpuMat::upload 的长时间延迟

C++: Long delay on cv::gpu::GpuMat::upload after upgrade to GTX970

我在我的程序中使用OpenCV的gpu模块(cuda)有一段时间了,它运行良好。现在我把我的显卡升级到了 gtx970。现在,我在启动程序后第一次调用 cv::gpu::GpuMat::upload 时出现了很长的延迟。使用我的旧显卡 (GTX770) 这几乎是瞬间完成的。

示例:我有一张尺寸为 512x600 像素的图像。使用此图像需要 12 秒。如果我在不关闭程序的情况下再次执行相同的代码,它会立即运行。我知道启动程序后第一次执行CUDA代码是在GPU上编译的,所以有一定的延迟是正常的。但对我来说,这似乎是莫名其妙的长,尤其是因为它使用旧卡要快得多。

有谁知道是什么导致了这种行为?与 GTX970 卡相关的当前 OpenCV 版本是否存在任何已知问题?我使用的版本是2.4.10,除了3.0beta,是最新的

我现在也发现了专门支持GTX970和GTX980卡的CUDA Toolkit的Release:

https://developer.nvidia.com/cuda-dow...

我下载了它,用那个编译了一遍OpenCV。不幸的是,这并没有解决我的问题。不知怎的,我觉得现在需要更长的时间。

这里有没有人对GTX900卡和OpenCV有任何经验?

这是代码,如果有人想看的话:

    if (_cudaAvailable){
        try{
            _gpuUploadMutex.lock();
            //upload image channels to the gpu if using cuda
            cv::gpu::GpuMat gpuMat;
            gpuMat.upload(_originalImage);
            cv::gpu::split(gpuMat, _originalImageChannelsCuda);
            _gpuUploadMutex.unlock();
            std::cout << "Image uploaded to GPU successfully" << std::endl;
        }
        catch (...){
            std::cerr << "Error occured while using CUDA, falling back to CPU. (Insufficient video RAM?)" << std::endl;
            _cudaAvailable = false;
            _gpuUploadMutex.unlock();
        }
    }

没什么特别的。导致初始延迟的代码行是 gpuMat.upload.

当您的程序尝试在 GPU 上执行代码时,驱动程序将检查可执行文件以在您的特定 GPU 上找到合适的代码 运行。可执行文件称为 "fat binary",这意味着它可以包含多种体系结构的代码。

在 GPU 的情况下,可执行文件可以包含不同 GPU 的机器代码以及 PTX,PTX 是一种稍微高级的语言(看起来像汇编语言),可以在 运行 时间编译到特定 GPU。

在您的情况下,我猜测二进制文件包含原始 GPU 的机器代码(GTX770 的计算能力为 3.0),但不包含新 GPU 的机器代码(GTX970 的计算能力为 5.2)。因此,当您在新 GPU 上 运行 时,驱动程序会找到 PTX(也包含在 fat 二进制文件中)并将其重新编译为 sm5.2。重新编译需要时间。

如果你能找到你的编译命令,你会看到类似这样的内容:

nvcc ... -gencode arch=compute_30,code=\'compute_30,sm_30\'

您应该更改为:

nvcc ... -gencode arch=compute_30,code=\'compute_30,sm_30,sm_52\'