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