函数说明
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
运行结果:
结果说明:
随机性并行
如果想要完成打印,则加入锁机制,如下示例
#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_ 对应的循环函数会被重复执行,因此对变量的赋值声明操作也会被重复执行,在使用中需要注意。