我想在OpenMP的帮助下并行化这些代码,例如 #pragma omp parallel for
,以将工作分成不同的线程。与SETS一起使用openMP
什么将是一种有效的方式?这里level是在多个线程之间共享的。
这里是一个集合。
for(iter=make.at(level).begin();iter!=make.at(level).end();iter++)
{
Function(*iter);
}
我想在OpenMP的帮助下并行化这些代码,例如 #pragma omp parallel for
,以将工作分成不同的线程。与SETS一起使用openMP
什么将是一种有效的方式?这里level是在多个线程之间共享的。
这里是一个集合。
for(iter=make.at(level).begin();iter!=make.at(level).end();iter++)
{
Function(*iter);
}
如果make.at(level)
返回的类型有持续访问时间如果你的编译器支持最新足够的OpenMP版本随机访问迭代器(读:这是不 MSVC++),那么你可以直接使用parallel for
工作共享指令:
obj = make.at(level);
#pragma omp parallel for
for (iter = obj.begin(); iter != obj.end(); iter++)
{
Function(*iter);
}
如果该类型不提供拉多姆访问迭代器,但仍然你的编译器支持OpenMP的3.0或更新版本,那么你可以使用OpenMP的任务:
#pragma omp parallel
{
#pragma omp single
{
obj = make.at(level);
for (iter = obj.begin(); iter != obj.end(); iter++)
{
#pragma omp task
Function(*iter);
}
}
}
这里一个线程执行for循环并创建许多OpenMP任务。每项任务将使用相应的值*iter
对Function()
进行一次调用。然后,每个空闲线程将开始从未完成的任务列表中选取。在并行区域的末尾存在一个隐含的障碍,所以主线程将在继续执行并行区域之前尽职地等待所有任务完成。
如果你不幸用微软的Visual C++,那么你就没有多少选择的余地,而不是创建对象的指针数组,并使用一个简单的整数循环迭代它:
obj = make.at(level);
obj_type* elements = new obj_type*[obj.size()];
for (i = 0, iter = obj.begin(); i < obj.size(); i++)
{
elements[i] = &(*iter++);
}
#pragma omp parallel for
for (i = 0; i < obj.size(); i++)
{
Function(*elements[i]);
}
delete [] elements;
这不是最优雅的解决方案,但它应该工作。
编辑:如果我从你的问题的标题正确理解,你正在使用集合。这排除了第一个算法,因为集合不支持随机访问迭代器。取决于编译器对OpenMP任务的支持,使用第二种或第三种算法。
似乎并行中的变量必须为int。但我不确定。这是一个关于这个的话题。 Why must loop variables be signed in a parallel for?
要使用使用OpenMP这个迭代器模式可能需要如何进行循环重新思考 - 你不能用#pragma omp for
,因为你的循环不是一个简单的整数循环。我不知道下面将工作:
iter = make.at(level).begin();
end = make.at(level).end();
#pragma omp parallel private(iter) shared(make,level,end)
{
#pragma omp single
func(iter); /* only one thread does the first item */
while (1)
{
#pragma omp critical
iter = make.at(level).next(); /* each thread gets a different item */
if (iter == end)
break;
func(iter);
}
} /* end parallel block */
注意,我不得不改变你的iter++
进入临界区一个next()
调用,使其工作。原因是共享的对象需要记住哪些项目已经被处理。