c++ - openmp parallel for with non-PODs

标签 c++ multithreading thread-safety openmp

我正在尝试加速一个程序,该程序的核心是一个看起来很普通的循环:

double sum=0.;
#pragma omp parallel for reduction(+:sum) // fails
for( size_t i=0; i<_S.size(); ++i ){
  sum += _S[i].first* R(atoms,_S[i].second) ;
}

虽然循环本身很简单,但其中的对象不是 POD:这里的 _S 实际上是一个 std::vector< std::pair<double, std::vector<size_t> > > , 和 R(...)是重载 operator(...) const一些对象。它的两个参数都符合 const 的条件。 ,这样调用就没有任何副作用。

由于大约 90% 的运行时间都花在了这个调用上,因此将 OpenMP pragma 放入如上所示并享受两到三倍的加速似乎是一件简单的事情; 但当然---代码在单个线程下工作正常,但对于多个线程给出明显错误的结果:-)。

没有数据依赖,两者都是_SR(...)在线程之间共享似乎是安全的,但它仍然会产生废话。

我非常感谢任何关于如何找出问题所在的指示。

UPD2:

想通了。与所有错误一样,它是微不足道的。 R(...)正在调用 operator()这类东西:

class objR{
 public:
   objR(const size_t N){
     _buffer.reserve(N);
   };
   double operator(...) const{
     // do something, using the _buffer to store intermediaries
   }

 private:
   std::vector<double> _buffer;
};

很明显,不同的线程使用 _buffer同时把它搞砸。到目前为止,我的解决方案是分配更多空间(内存不是问题,代码受 CPU 限制):

class objR{
 public:
   objR(const size_t N){
     int nth=1;
     #ifdef _OPENMP
       nth=omp_get_max_threads();
     #endif
     _buffer.resize(N);
   }

   double operator(...) const{
     int thread_id=0;
     #ifdef _OPENMP
       thread_id = omp_get_thread_num();
     #endif
     // do something, using the _buffer[thread_id] to store intermediaries
   }

 private:
   std::vector< std::vector<double> > _buffer;
};

这似乎工作正常。尽管如此,由于这是我第一次涉足多线程事物,如果有知识渊博的人可以评论是否有更好的方法,我将不胜感激。

最佳答案

访问 _S[i].first_S[i].second 是绝对安全的(不能保证任何关于 atom).这意味着您对 R 的函数调用一定是导致问题的原因。您需要了解什么是 R 并发布它的作用。

另一方面,以下划线开头和大写字符开头的名称保留用于实现,您可以通过使用它们来调用未定义的行为。

关于c++ - openmp parallel for with non-PODs,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6285715/

相关文章:

c++ - 如何使用 gcc-linaro-arm-linux-gnueabihf-objdump 使用源代码行和文件名分解二进制文件?

c++ - 如何在sqlite准备好的语句中处理空值

c++ - C++ 有 "not equal compare and exchange"或 "fetch add on not equal"吗?

c++ - Qt UIThreadWidget

C++ 设置 TDateTime 变量

C++:在相等性测试中使用基类的私有(private)成员

python - 将 win32com 与多线程一起使用

c - 如果我向一个条件变量发出 N 次信号,它会解锁 N 个线程吗?

c# - 如何创建一个Lockfree集合集合

asp.net - 网页中运行的线程