android+opencv+opencl: cv::dft()的opencl版本的性能分析

在小米mix 2s + 高通骁龙 845 + Adreno 630 上测试了opencl版本的cv::dft()。

测试数据

先看表格里面的描述:

名称函数名最大时间(ms)平均时间(ms)说明
cpu版本dftcv::dft()-0.029448未统计其他,仅cv::dft()函数的调用时间
opencl版本cv::dft(UMat)802.5570000.202941不计算mat与umat的拷贝,不计算umat的填充对齐
opencl中使用opencl计算的主函数cv::ocl_dft()802.5530000.210583cv::dft()包装了cv::ocl_dft(),这一层无太多性能损耗
ocl_dft第一步调用的子函数ocl_dft_rows()802.5180000.1031-
ocl_dft第二步调用的子函数ocl_dft_cols()338.0040000.078061-
对象池OCL_FftPlanCache::getInstance().getFftPlan()0.1900000.000028对象池很快,几乎不占用时间,可以忽略
opencl的核函数编译、绑定参数、计算OCL_FftPlan::enqueueTransform()464.3930000.075685-
核函数编译enqueueTransform()464.2370000.019422第一次编译很慢,以后会快很多。但是也不用重复编译才对
参数绑定enqueueTransform()0.1220000.016015绑定参数也很快
核函数执行enqueueTransform()1.1670000.028805-

结果分析

有这样一些结论:

  • 令人失望:opencl+gpu版本的平均时间 0.202941,而CPU版本的平均时间是 0.029448,GPU版本比CPU版本慢了6.9倍;而且还未加上Mat拷贝到UMat, Mat填充对齐,UMat拷贝回Mat等部分占用的时间;
  • 可以发现,第一次执行cv::dft()的opencl版本的时候,编译核函数很耗时(464ms),后续的编译占用时间尚可;
  • 纯计算时间上看,opencl核函数执行时间大约是0.028805 * 2,大约是CPU版本的1.96倍。产生这样的原因可能是我的测试数据很小,如果数据量很大,GPU版本在纯计算时间上可能会比CPU版本好一些。

优化计划

  • 在调用cv::dft()的opencl版本以前,开一个线程空调用一次cv::ocl_dft(),这样核函数的编译时间就不会占用总调用时间了。
  • ocl::Kernel这里可以建立对象池,而不是每次调用都使用临时对象,这样的话,每次调用可以节约0.019422ms,性能可提升9.6%;
ocl::Kernel k(kernel_name.c_str(), ocl::core::fft_oclsrc, options);
  • 如果采用GPU内存池,每次计算的输入和输出地址都不变,那么参数绑定环节的0.016015ms可以省略,性能可能提升7.9%
  • 在我的cv::dft()的使用场景中,每次连续计算44个矩阵的数据。假设能够找到方法,把44次计算陆续加入队列,让GPU连续计算。假设GPU并发度支持44次计算同时进行,那么GPU版本的理论延迟是 0.202941/44 = 0.004612, 比CPU版本提升 6.39倍!

转载于:https://www.cnblogs.com/ahfuzhang/p/11097141.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值