当前位置: 首页 > news >正文

opencv parallel_for_使用及注意

文章目录

    • 函数说明
    • 使用demo
    • 循环函数中变量操作测试
      • 全局变量测试
      • 局部变量测试
    • 其他使用示例
    • 其他并行用法
    • 结论

函数说明

parallel_for_用于并行处理循环操作

使用demo

parallel_for_使用,简单示例,func函数循环调用

#include <iostream>
#include <opencv2/core.hpp>

using namespace std;
using namespace cv; 

void fun (const Range range)
{
  for (size_t i = range.start; i < range.end; i++) {
    cout << "i: " << i << endl;
  }
}

int main ()
{
  parallel_for_(cv::Range(0, 10), &fun);
  return 0;
}

编译命令:

g++ parallel_for_.cpp `pkg-config --libs --cflags opencv` -o demo1

运行:
./a.out

运行结果:
/home/niebaozhen/tmp/parallel/demo1.png
结果说明:
随机性并行

如果想要完成打印,则加入锁机制,如下示例

#include <iostream>
#include <opencv2/core.hpp>
#include <mutex>

mutex t_mutex;

void fun (const Range range)
{
  for (size_t i = range.start; i < range.end; i++) {
    {unique_lock<mutex> lck(t_mutex);
    cout << "i: " << i << endl;}
  }
}

int main ()
{
  parallel_for_(cv::Range(0, 10), &fun);
  return 0;
}

运行结果:
在这里插入图片描述

循环函数中变量操作测试

全局变量测试

测试全局变量在循环函数被并行执行的情况

int t = 0;

int fun (const Range range)
{
  for (size_t i = range.start; i < range.end; i++) {
    cout << "i: " << i << endl;
    t += i;
  }

  return t;
}

int main ()
{
  parallel_for_(cv::Range(0, 10), &fun);

  cout << "t: " << t << endl;
  return 0;
}

运行结果:
在这里插入图片描述
全局变量在较少的并行中,未出现竞争现象,但是仍存在线程安全问题,需加入锁机制,如下:

int t = 0;

int fun (const Range range)
{
  for (size_t i = range.start; i < range.end; i++) {
    {unique_lock<mutex> lck(t_mutex);
    cout << "i: " << i << endl;
    t += i;}
  }

  return t;
}

int main ()
{
  parallel_for_(cv::Range(0, 10), &fun);

  cout << "t: " << t << endl;
  return 0;
}

当对全局变量在循环函数内进行赋值操作时,将会出现问题,如下:

int t = 0;

int fun (const Range range)
{
  //this will make error
  t = 0;
  for (size_t i = range.start; i < range.end; i++) {
    cout << "i: " << i << endl;
    t += i;
  }

  return t;
}

int main ()
{
  parallel_for_(cv::Range(0, 10), &fun);

  cout << "t: " << t << endl;
  return 0;
}

运行结果:
在这里插入图片描述
结果分析:
循环函数中,整个函数会被重复执行,即使变量赋值发生在for循环之外,如下代码

void fun (const Range range)
{
  cout << "test*******" << endl;

  for (size_t i = range.start; i < range.end; i++) {}
}

int main ()
{
  parallel_for_(cv::Range(0, 10), &fun);

  return 0;
}

运行结果:
在这里插入图片描述

局部变量测试

int t = 0;
int fun (const Range range)
{

  //this will make error
  int t1 = 0;
  for (size_t i = range.start; i < range.end; i++) {
    cout << "i: " << i << endl;
    t1++;
  }

  t = t1;
  return t;
}

int main ()
{
  parallel_for_(cv::Range(0, 10), &fun);

  cout << "t: " << t << endl;
  return 0;
}

测试结果:
在这里插入图片描述
结果分析:
循环函数中只能使用常量,对变量进行操作会产生其他问题

其他使用示例

     cv::parallel_for_(cv::Range(0, px_ref.size()),
     std::bind(&JacobianAccumulator::accumulate_jacobian_se3_FA, this,
     std::placeholders::_1));

std::bind(&JacobianAccumulator::accumulate_jacobian_se3_FA, this, std::placeholders::_1) 定义了一个xxx(Range)的函数,并将地址赋值给了parallel_for_,parallel_for_将参数给xxx(Range),xxx调用accumulate_jacobian_se3_FA(Range)
由于c++类成员函数指针的访问特性,所以需要中间中转一下通过bind生成一个xxx(Range)的函数。

其他并行用法

#pragma omp parallel for是OpenMP中的一个指令,表示接下来的for循环将被多线程执行,另外每次循环之间不能有关系。示例如下:

int main(int argc, char* argv[])
{
#pragma omp parallel for  //后面是for循环
     for (int i = 0; i < 10; i++ )
     {
         printf("i = %d/n", i);
     }
     return 0;
}

这个程序执行后打印出以下结果:

i = 0
i = 5
i = 1
i = 6
i = 2
i = 7
i = 3
i = 8
i = 4
i = 9

结论

parallel_for_ 对应的循环函数会被重复执行,因此对变量的赋值声明操作也会被重复执行,在使用中需要注意。

相关文章:

  • 拿下国产高端市场第一背后,vivo与苹果、华为的共性
  • postgresql 实现变量替换框架
  • numpy在数字图像处理中的应用
  • A tour of gRPC:09 - gRPC Interceptor 拦截器
  • 【Docker】——Network
  • Vue3如何实现全屏模式
  • 新型数据中心网络安全体系研究
  • Android获取手机电压,电流,电量,BatteryManager
  • 光纤通信数字孪生系统架构及关键技术研究
  • 数据结构与算法复习:第三十四弹
  • 元宇宙会场APP功能系统软件源码开发
  • 【反诈拒赌 支付在行动】涉赌资金转移典型案例及风险提示
  • 【Python黑科技】把秘密写在照片里(保姆级图文+实现代码)
  • OpenGL ES学习(7)——混合
  • Spoon Kettle 连接之记录集连接详解(Merge join)
  • 2018天猫双11|这就是阿里云!不止有新技术,更有温暖的社会力量
  • Hibernate【inverse和cascade属性】知识要点
  • input实现文字超出省略号功能
  • java B2B2C 源码多租户电子商城系统-Kafka基本使用介绍
  • vue-loader 源码解析系列之 selector
  • 表单中readonly的input等标签,禁止光标进入(focus)的几种方式
  • 给初学者:JavaScript 中数组操作注意点
  • 浅析微信支付:申请退款、退款回调接口、查询退款
  • 三栏布局总结
  • 手写双向链表LinkedList的几个常用功能
  • 小程序上传图片到七牛云(支持多张上传,预览,删除)
  • 赢得Docker挑战最佳实践
  • CMake 入门1/5:基于阿里云 ECS搭建体验环境
  • ​草莓熊python turtle绘图代码(玫瑰花版)附源代码
  • ## 临床数据 两两比较 加显著性boxplot加显著性
  • #LLM入门|Prompt#1.7_文本拓展_Expanding
  • #经典论文 异质山坡的物理模型 2 有效导水率
  • (12)目标检测_SSD基于pytorch搭建代码
  • (2/2) 为了理解 UWP 的启动流程,我从零开始创建了一个 UWP 程序
  • (8)Linux使用C语言读取proc/stat等cpu使用数据
  • (Python第六天)文件处理
  • (蓝桥杯每日一题)平方末尾及补充(常用的字符串函数功能)
  • (四)图像的%2线性拉伸
  • (学习日记)2024.04.10:UCOSIII第三十八节:事件实验
  • (一)搭建springboot+vue前后端分离项目--前端vue搭建
  • .NET 4 并行(多核)“.NET研究”编程系列之二 从Task开始
  • .NET Framework .NET Core与 .NET 的区别
  • .NET Framework 和 .NET Core 在默认情况下垃圾回收(GC)机制的不同(局部变量部分)
  • .NET MVC、 WebAPI、 WebService【ws】、NVVM、WCF、Remoting
  • .NET NPOI导出Excel详解
  • .NET Remoting学习笔记(三)信道
  • .net6Api后台+uniapp导出Excel
  • .NET国产化改造探索(三)、银河麒麟安装.NET 8环境
  • .net快速开发框架源码分享
  • @CacheInvalidate(name = “xxx“, key = “#results.![a+b]“,multi = true)是什么意思
  • [ CTF ] WriteUp- 2022年第三届“网鼎杯”网络安全大赛(朱雀组)
  • [ CTF ] WriteUp-2022年春秋杯网络安全联赛-冬季赛
  • [ NOI 2001 ] 食物链
  • [ 云计算 | AWS 实践 ] 基于 Amazon S3 协议搭建个人云存储服务
  • [<MySQL优化总结>]