• opencv之并行计算多线程parallel_for_


    目录

    一、前言

    二、加速案例

    三、代码分析      


    一、前言

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

    二、加速案例

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

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

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

    1. #include
    2. using namespace cv;
    3. #include // std::iota
    4. const int g_num = 10000;
    5. // 单线程
    6. void my_test1(double* p_arr)
    7. {
    8. for (size_t i = 0; i < g_num; i++)
    9. {
    10. int p_arr_i = p_arr[i];
    11. for (size_t j = 0; j < g_num; j++)
    12. {
    13. double num1 = p_arr_i * (j > 10 ? 10 : j);
    14. double num2 = std::pow(num1, 2);
    15. double num3 = std::sqrt(num2);
    16. p_arr[i] = num3;
    17. p_arr[i] = p_arr_i * num3;
    18. p_arr[i] = p_arr[i] / num3;
    19. }
    20. }
    21. }
    22. // 多线程
    23. void my_test2(double* p_arr)
    24. {
    25. parallel_for_(Range(0, g_num), [&](const Range& r)
    26. {
    27. for (int oc = r.start; oc < r.end; oc++)
    28. {
    29. // 类似于cuda核函数部分
    30. int p_arr_i = p_arr[oc];
    31. for (size_t j = 0; j < g_num; j++)
    32. {
    33. double num1 = p_arr_i * (j > 10 ? 10 : j);
    34. double num2 = std::pow(num1, 2);
    35. double num3 = std::sqrt(num2);
    36. p_arr[oc] = num3;
    37. p_arr[oc] = p_arr_i * num3;
    38. p_arr[oc] = p_arr[oc] / num3;
    39. }
    40. }
    41. });
    42. }
    43. int main()
    44. {
    45. double numbers[g_num];
    46. int st = 0;
    47. std::iota(numbers, numbers + g_num, st); // 100 101 102 103
    48. double t = (double)getTickCount();
    49. my_test1(numbers);
    50. t = (double)getTickCount() - t;
    51. double t2 = (double)getTickCount();
    52. my_test2(numbers);
    53. t2 = (double)getTickCount() - t2;
    54. printf("my_test1 costs time = %.1fms\n", t * 1000 / getTickFrequency());
    55. printf("my_test2 costs time = %.1fms\n", t2 * 1000 / getTickFrequency());
    56. system("pause");
    57. return 0;
    58. }

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

    三、代码分析      

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

    1. parallel_for_(Range(0, g_num), [&](const Range& r)
    2. {
    3. for (int oc = r.start; oc < r.end; oc++)
    4. {
    5. // 代码中并行部分,类似于核函数部分
    6. int p_arr_i = p_arr[oc];
    7. for (size_t j = 0; j < g_num; j++)
    8. {
    9. double num1 = p_arr_i * (j > 10 ? 10 : j);
    10. double num2 = std::pow(num1, 2);
    11. double num3 = std::sqrt(num2);
    12. p_arr[oc] = num3;
    13. p_arr[oc] = p_arr_i * num3;
    14. p_arr[oc] = p_arr[oc] / num3;
    15. }
    16. }
    17. });

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

    1. for (size_t i = 0; i < g_num; i++)
    2. {
    3. int p_arr_i = p_arr[i];
    4. for (size_t j = 0; j < g_num; j++)
    5. {
    6. double num1 = p_arr_i * (j > 10 ? 10 : j);
    7. double num2 = std::pow(num1, 2);
    8. double num3 = std::sqrt(num2);
    9. p_arr[i] = num3;
    10. p_arr[i] = p_arr_i * num3;
    11. p_arr[i] = p_arr[i] / num3;
    12. }
    13. }

  • 相关阅读:
    第100+15步 ChatGPT学习:R实现Ababoost分类
    【计算机毕业设计】奖学金管理系统源码
    基于JAVA乐购游戏商城系统计算机毕业设计源码+数据库+lw文档+系统+部署
    基于STC12C5A60S2系列1T 8051单片机实现串口调试助手软件与单片机相互发送数据的RS485通信功能
    ubuntu20.04.5 LTS搭建高可用k3s集群
    软件测试概率性问题
    NC102 在二叉树中找到两个节点的最近公共祖先(C++)- 中等、树
    新手小白怎样开始学做自媒体呢?
    深入理解计算机系统——Midterm Exam 2012
    Istio网关流量转发
  • 原文地址:https://blog.csdn.net/m0_72734364/article/details/133427874