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

标签 c++ opencv cuda gpu

我在我的程序中使用 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(也包含在 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\'

关于C++:升级到 GTX970 后 cv::gpu::GpuMat::upload 出现长时间延迟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27795501/

相关文章:

CUDA 共享内存阵列 - 奇怪的行为

c++ - CUDA 矩阵加法段错误

c++ - OpenCV 或 Boost 智能指针

c++ - opencv 仍然使用 cuda 内存

python - 未检测到 ArUco 标记

c++ - 根据模板 C++ 的类型具有可变类型的类成员

c++ - 如何使用 ifstream 从文件中读取行?

c++ - 在 C++ 中通过 UDP 发送缓冲图像

c++ - 有没有保证 sizeof(which) > 1 的简单类型?

c++ - 我可以使用 std::unique_ptr<BaseClass>(&DerivedClass) 吗?