[英]Using openMP with SETS
我希望在OpenMP的帮助下将此代码#pragma omp parallel for
例如#pragma omp parallel for
以便在不同的线程之间划分工作。
什么是有效的方式? 这里的级别在varioud线程之间共享。
这里是一套。
for(iter=make.at(level).begin();iter!=make.at(level).end();iter++)
{
Function(*iter);
}
如果make.at(level)
返回的类型具有随机访问迭代器并具有持续访问时间,并且如果您的编译器支持最新的OpenMP版本(读取:它不是 MSVC ++),那么您可以直接使用parallel for
worksharing指令:
obj = make.at(level);
#pragma omp parallel for
for (iter = obj.begin(); iter != obj.end(); iter++)
{
Function(*iter);
}
如果类型不提供radom-access迭代器,但您的编译器仍然支持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()
进行一次调用。 然后每个空闲线程将从未完成任务列表中开始挑选。 在并行区域的末尾有一个隐式屏障,因此主线程将尽职地等待所有任务完成,然后继续执行并行区域。
如果你不幸使用MS 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任务的支持,使用第二种或第三种算法。
似乎并行中的变量必须是signed int。 但我不确定。 这是一个关于此的话题。 为什么循环变量必须并行签名?
要在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()
调用才能使其正常工作。 原因是共享的make.at(level)
对象需要记住哪些项已经被处理。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.