C++:升级到 GTX970 后,cv::gpu:GpuMat::upload 延迟较长

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

本文关键字:GpuMat gpu upload cv 延迟 GTX970 C++      更新时间:2023-10-16

我已经在我的程序中使用OpenCV的GPU模块(cuda)一段时间了,它工作得很好。现在我将显卡升级到 gtx970。现在,当我在启动程序后第一次调用cv::gpu::GpuMat::upload时,我得到了很长的延迟。使用我的旧显卡(GTX770),这几乎立即完成。

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

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

我现在还发现有一个专门支持 GTX970 和 GTX980 卡的 CUDA 工具包版本:

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 上运行的代码。可执行文件被称为"胖二进制文件",这意味着它可以包含多个体系结构的代码。

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

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

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

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

您应该更改为:

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