当前位置:   article > 正文

opencv parallel_for_使用及注意_for(cv::point pnt : lst)

for(cv::point pnt : lst)

函数说明

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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

编译命令:

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

运行:
./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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

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

循环函数中变量操作测试

全局变量测试

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

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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

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

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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

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

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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

运行结果:
在这里插入图片描述
结果分析:
循环函数中,整个函数会被重复执行,即使变量赋值发生在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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

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

局部变量测试

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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

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

其他使用示例

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

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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

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

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

结论

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/657423
推荐阅读
相关标签
  

闽ICP备14008679号