opencv之并行计算多线程parallel_for_

目录

一、前言

二、加速案例

三、代码分析      


一、前言

        OpenCV提供了多线程处理的API。从OpenCV 4.5版本开始,它引入了对C++11标准的并行算法的支持。这意味着你可以使用多线程来加速你的OpenCV代码。在OpenCV中,利用parallel_for_接口实现并行加速。

二、加速案例

        先看一个案例,以下代码中,有两个函数:

  • my_test1() 函数就是一个最常见的串行处理函数(默认随便将10000个数进行加减乘除);
  • my_test2() 函数是利用parallel_for_实现并行处理。

注意:opencv使用的版本是4.5。

#include<opencv2/opencv.hpp>
using namespace cv;
#include <numeric> // std::iota 

const int g_num = 10000;

// 单线程
void my_test1(double* p_arr)
{
     for (size_t i = 0; i < g_num; i++)
     {
         int p_arr_i = p_arr[i];
         for (size_t j = 0; j < g_num; j++)
         {
              double num1 = p_arr_i * (j > 10 ? 10 : j);
              double num2 = std::pow(num1, 2);
              double num3 = std::sqrt(num2);
              p_arr[i] = num3;
              p_arr[i] = p_arr_i * num3;
              p_arr[i] = p_arr[i] / num3;
         }
     }
}


// 多线程 
void my_test2(double* p_arr)
{
     
     parallel_for_(Range(0, g_num), [&](const Range& r)
         {
             for (int oc = r.start; oc < r.end; oc++)
             {
                 // 类似于cuda核函数部分
                 int p_arr_i = p_arr[oc];
                 for (size_t j = 0; j < g_num; j++)
                 {
                     double num1 = p_arr_i * (j > 10 ? 10 : j);
                     double num2 = std::pow(num1, 2);
                     double num3 = std::sqrt(num2);
                     p_arr[oc] = num3;
                     p_arr[oc] = p_arr_i * num3;
                     p_arr[oc] = p_arr[oc] / num3;
                 }
             }
         });
 }
 
int main()
{
     double numbers[g_num];
     int st = 0;
     std::iota(numbers, numbers + g_num, st); // 100 101 102 103 
 
 
     double t = (double)getTickCount();
     my_test1(numbers);
     t = (double)getTickCount() - t;
 
     double t2 = (double)getTickCount();
     my_test2(numbers);
     t2 = (double)getTickCount() - t2;
 
     printf("my_test1 costs time = %.1fms\n", t * 1000 / getTickFrequency());
     printf("my_test2 costs time = %.1fms\n", t2 * 1000 / getTickFrequency());
 
 
     system("pause");
     return 0;
}

如下图,my_test2函数执行速度是my_test1的10倍!

三、代码分析      

 对于opencv这个多线程加速(其他加速框架,例如cuda也是同理),任务必须足够复杂再有加速效果,例如:数组中,每个像素+1这种简单的任务,还不如for循环单线程快。另外就是,opencv这个并行API:parallel_for_使用简单,无非就是把适合并行的“核函数”部分写到合适位置,例如:

parallel_for_(Range(0, g_num), [&](const Range& r)
        {
            for (int oc = r.start; oc < r.end; oc++)
            {
                // 代码中并行部分,类似于核函数部分
                int p_arr_i = p_arr[oc];
                for (size_t j = 0; j < g_num; j++)
                {
                    double num1 = p_arr_i * (j > 10 ? 10 : j);
                    double num2 = std::pow(num1, 2);
                    double num3 = std::sqrt(num2);
                    p_arr[oc] = num3;
                    p_arr[oc] = p_arr_i * num3;
                    p_arr[oc] = p_arr[oc] / num3;
                }
            }
        });

以下是串行处理代码,和上面并行代码对比,写法其实差不多。

for (size_t i = 0; i < g_num; i++)
     {
         int p_arr_i = p_arr[i];
         for (size_t j = 0; j < g_num; j++)
         {
              double num1 = p_arr_i * (j > 10 ? 10 : j);
              double num2 = std::pow(num1, 2);
              double num3 = std::sqrt(num2);
              p_arr[i] = num3;
              p_arr[i] = p_arr_i * num3;
              p_arr[i] = p_arr[i] / num3;
         }
     }

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

黄家驹beyond

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值