Omp最大减少与存储索引
omp max reduction with storage of index
使用c++ openmp 3.1,我实现了一个max reduction,它存储了对象向量的整数变量(分数)的最大值。但我也想存储向量索引以访问具有最大分数的对象。我目前不成功的实现是这样的:
//s is a vector of sol objects which contain apart from other variables an integer score variable s[].score
int bestscore = 0;
int bestant = 0;
#pragma omp parallel shared(bestant)
{//start parallel session
#pragma omp for nowait reduction(max : bestscore)
for (int ant = 0; ant<maxsols; ++ant) // for all ants
{
//procedures on s[ant] object which update the int s[ant].score
if (s[ant].score > bestscore)
{
//find the object with the highest score
bestscore = s[ant].score;
bestant = ant;//i also want know which ant has the highest score
}
}
}
代码编译并运行。找到最大bestscore,但bestant得到一个随机索引。连接到最快完成线程的蚂蚁被存储在bestant中。Bestscore以0开始,所以在大多数情况下s[ant]。分数将有更高的分数,最好的分数和最好的是更新。我想我需要一个简化运算符bestant像"on update of bestscore"。
bestant
获得随机索引i
的原因(如您所怀疑的)是因为bestant
是共享的,并且不像bestscore
那样从缩减子句中受益。Z玻色子提出的解决方案很好:critical
指令块由线程只执行一次,这样开销应该是有限的。
您当时使用的是OpenMP 3.1运行时。我想解释一下,这个限制从OpenMP 4.0开始就已经解决了。现在你可以编写一个用户定义的操作符(参见2.19.5.7 declare reduction Directive)。
在这种情况下,解决方案可以是将这两个值打包到结构体和定义两个这样的struct元素如何在#pragma parallel for
循环结束时组合。
//s is a vector of sol objects which contain apart from other variables an integer score variable s[].score
typedef struct {
int score;
int ant;
} best_t;
best_t best = { 0, 0 };
// we declare our user reduction operator :
// it is called get_max, return a a value of type best_t.
// omp_out and omp_in are the predefined names of two private elements
// to combine in the end to the final shared variable.
#pragma omp declare reduction(get_max : best_t :
omp_out = omp_out.score > omp_in.score ? omp_out : omp_in)
initializer (omp_priv=(omp_orig))
#pragma omp parallel
{//start parallel session
#pragma omp for nowait reduction(get_max : best)
for (int ant = 0; ant<maxsols; ++ant) // for all ants
{
//procedures on s[ant] object which update the int s[ant].score
if (s[ant].score > best.score)
{
//find the object with the highest score
best.score = s[ant].score;
best.ant = ant;
}
}
}
试试这个
int bestscore = 0;
int bestant = 0;
#pragma omp parallel
{
int bestscore_private = 0;
int bestant_private = 0;
#pragma omp for nowait
for (int ant = 0; ant<maxsols; ++ant) {
if (s[ant].score > bestscore_private) {
bestscore_private = s[ant].score;
bestant_private = ant;
}
}
#pragma omp critical
{
if(bestscore_private>bestscore) {
bestscore = bestscore_private;
bestant = besant_private;
}
}
}
两点观察:
-
我认为你只需要比较
bestscore_private
和bestscore
时,它的值被改变,这样比较的次数减少。 -
此外,至少在今天的omp中,您可以在if条件中使用临界区,这样
bestscore_private
和bestscore
之间的比较将并行进行,并且不经常(希望如此)更新到bestscore
将以临界方式进行。int bestscore = 0;Int bestant = 0;#pragma omp parallel{
int bestscore_private = 0; int bestant_private = 0; #pragma omp for nowait for (int ant = 0; ant<maxsols; ++ant) { if (s[ant].score > bestscore_private) { bestscore_private = s[ant].score; bestant_private = ant; if(bestscore_private>bestscore){ #pragma omp critical { bestscore = bestscore_private; bestant = besant_private; } } } }
}
- 如何对存储为"Compressed Sparse Row"的矩阵进行稀疏矩阵索引?
- 一个 2D 数组,并按行存储值.第一个循环用于行索引,第二个循环用于列索引
- 如何用索引命名一个变量来存储输入 mxArray?
- C++ - 浮点数组在某个非常大的索引之后不存储值
- 存储将单个查询图像与多个图像的列表匹配的关键点索引
- 用于存储网格(将具有负索引)的数据结构
- 使用索引将 BST 值存储到数组中
- C ++将文本存储在数组的不同索引中,并带有一两个
- 如何在C++中找到存储在多集特定索引中的值?
- 可以在同一 VBO 中存储不同的顶点属性和索引
- 如何知道我想在数组中存储多少索引
- 如何将元素的索引从2D数组存储到1D数组中,然后交换这些值
- 将索引存储在向量<集合<int>>与向量<向量中<int>>
- 存储Boost Multi_index索引迭代器
- 几对性能问题(一个较大的向量与较小的块向量),值得存储迭代索引以进行矢量访问
- 对整个垫子图像进行排序并在 OpenCV 中存储索引
- 如何将整数存储在字符数组的单个索引中
- 如何将数组索引存储在映射中
- libSpatialIndex:在磁盘上加载/存储索引
- Omp最大减少与存储索引