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(); }