openMP增量在线程之间添加int?

Posted

技术标签:

【中文标题】openMP增量在线程之间添加int?【英文标题】:openMP increment add int among threads? 【发布时间】:2018-02-09 00:13:13 【问题描述】:

我正在尝试对下面的函数进行多线程处理。我无法让计数器在 OpenMP 线程之间正确共享,我尝试了 atomic 和 int,atomic 似乎不起作用,INT 也没有。不确定,我迷路了,我该如何解决?

  std::vector<myStruct> _myData(100);
    int counter;
    counter =0
    int index;
#pragma  omp parallel for private(index)
    for (index = 0; index < 500; ++index) 
        if (data[index].type == "xx") 
            myStruct s;
            s.innerData = data[index].rawData
            processDataA(s); // processDataA(myStruct &data)
            processDataB(s);
            _myData[counter++] = s; // each thread should have unique int not going over 100 of initially allocated items in _myData
        
    

编辑。更新错误的语法/缺失的部分

【问题讨论】:

您选择将索引设为私有是否有特殊原因? 不编译。 inxed 应该是 index 吗?请发帖minimal reproducible example 这似乎是解释为什么需要关键部分的典型示例。顺便说一句,不初始化就使用counter是不好的。 您需要更清楚地描述预期的行为是什么以及似乎不起作用意味着什么。特别是,_myData 中的结果必须是确定性排序的吗?另外,myStruct 是什么,processDataA,B 有多贵。了解这一点对于提供具有合理性能的建议至关重要。 @MikeCAT 如果数据竞争只涉及counter,我更喜欢使用原子操作而不是关键部分。即int temp; #pragma omp atomic capture temp = counter++; _myData[temp] = s;. 【参考方案1】:

如果你不能使用 OpenMP atomic capture,我会尝试:

std::vector<myStruct> _myData(100);
int counter = 0;
#pragma omp parallel for schedule(dynamic)
for (int index = 0; index < 500; ++index) 
   if (data[index].type == "xx") 
      myStruct s;
      s.innerData = data[index].rawData
      processDataA(s); 
      processDataB(s);
      int temp;
      #pragma omp critical
      temp = counter++;
      assert(temp < _myData.size());
      _myData[temp] = s; 
   

或者:

#pragma omp parallel for schedule(dynamic,c)

并试验块大小c

但是,原子可能比关键部分更有效。你的编译器应该支持某种形式的原子。


请注意,您的解决方案有点脆弱,因为它仅在循环内的条件评估为 true 小于 101x 时才有效。这就是我在代码中添加断言的原因。也许是更好的解决方案:

std::vector<myStruct> _myData;
size_t size = 0;
#pragma omp parallel for reduction(+,size)
for (int index = 0; index < data.size(); ++index)
   if (data[index].type == "xx") size++;
v.resize(size);
...

那么,你不需要关心向量的大小,也不会浪费内存空间。

【讨论】:

以上是关于openMP增量在线程之间添加int?的主要内容,如果未能解决你的问题,请参考以下文章

OpenMP:如何在每个线程中利用递归函数?

OpenMP 多线程更新同一个数组

OpenMP 中的并行累积(前缀)总和:线程之间的通信值

如何使用 OpenMP 将每个线程的输出返回到数组中?

OpenMP 中树结构的线程安全

如果已经定义了宏_OPENMP,它是一个int类型的十进制数。编写一个程序打印它的值,这个值的意义是啥?