C++ 在DFT OpenCV TAPI中UMat与Mat的速度
我发现了一些关于在C++ 在DFT OpenCV TAPI中UMat与Mat的速度,c++,performance,opencv,image-processing,C++,Performance,Opencv,Image Processing,我发现了一些关于在cv::UMats与cv::Mats上执行cv::dft函数的有趣结果。基本上,我发现,在图像高达4096x4096之前,UMats实际上要慢得多。在此之前,cv::Mat始终获胜。这是否仅仅是因为没有为TAPI api实现dft,而只为CV::Mat实现dft?我运行的测试如下所示(我使用celero项目创建基准测试): 我得到了以下结果: cv::UMat迭代次数/秒=4.51 cv::Mat迭代次数/秒=4.70 对于较小的图像,例如1024x1024,我得到以下结果:
cv::UMat
s与cv::Mat
s上执行cv::dft
函数的有趣结果。基本上,我发现,在图像高达4096x4096之前,UMat
s实际上要慢得多。在此之前,cv::Mat
始终获胜。这是否仅仅是因为没有为TAPI api实现dft,而只为CV::Mat实现dft?我运行的测试如下所示(我使用celero项目创建基准测试):
我得到了以下结果:
cv::UMat迭代次数/秒=4.51
cv::Mat迭代次数/秒=4.70
对于较小的图像,例如1024x1024,我得到以下结果:
cv::UMat迭代次数/秒=63.21
cv::Mat迭代次数/秒=85.83
从这些结果中,您可以看到,对于较大的图像,使用UMat几乎没有任何优势,对于较小的图像尤其没有优势。这让我感到惊讶,因为当切换到OpenCV TAPI时,我使用
cv::matchTemplate
获得了显著的速度提升。我的猜测是,cv::dft
没有在OpenCL中实现,但这真的是这样吗?DFT只是一个而不是好的算法,可以卸载到GPU上吗?谢谢 cv::dft
肯定有OpenCL实现,但在某些设备上可能没有优势(它最初针对英特尔集成GPU进行了优化)。你用什么GPU?另外请注意,您测量初始化步骤,对于UMat
来说,它可能非常慢。您是对的,创建cv::UMat
的速度较慢,但从我运行的实验来看,差异几乎可以忽略不计。尤其是在运行cv::matchTemplate
时,因为我使用cv::UMat
可以获得将近400倍的速度。我运行的GPU是AMD Radeon R9 M370X。您可以尝试使用clMath库支持构建opencv。该库包含AMD GPU的OpenCL实现。OpenCV有包装器(请使用_openclamdftcmake选项查找),我可以试一试。我还没有查看引擎盖下的内容,但是我很惊讶cv::matchTemplate
函数不会使用cv::dft
函数。也许他们只是做一个卷积?我得四处看看。cv::matchTemplate
仅当模板大小大于18*18时才使用cv::dft
。对于较小的模板,它使用自定义OpenCL内核执行简单的卷积。
constexpr int num_samples = 2;
constexpr int num_iterations = 10;
constexpr int num_rows = 4096;
constexpr int num_cols = 4096;
cv::UMat a = cv::UMat(num_rows, num_cols, CV_32F);
cv::Mat b = cv::Mat(num_rows, num_cols, CV_32F);
void CreateUMat() { cv::randu(a, 0, 256); }
void CreateMat() { cv::randu(b, 0, 256); }
void DftUMat() {
CreateUMat();
cv::dft(a, a);
cv::idft(a, a, cv::DFT_SCALE | cv::DFT_INVERSE);
}
void DftMat() {
CreateMat();
cv::dft(b, b);
cv::idft(b, b, cv::DFT_SCALE | cv::DFT_INVERSE);
}
BASELINE(UMatBenchmarks, Baseline, num_samples, num_iterations) { DftUMat(); }
BENCHMARK(UMatBenchmarks, NoGPU, num_samples, num_iterations) { DftMat(); }