由 小码哥发布于 2019-03-18 标签:c++openmpshared_ptrdatarace

标签 c++ openmp

我有一个 C++ 程序,我尝试在 for 循环中使用 openmp。 for 循环与我自己的类的 shared_ptr 一起工作,该类又调用另一个 dll。我收到错误:

Table 7. Current pointer and in_use_count are inconsistent.

代码看起来像这样..

    int n = 1000;
    std::vector<double> result(n),indata(n);

    // populate indata

    std::shared_ptr<MyNS::MyClass> sp_mycl = std::make_shared < MyNS::MyClass >();
    sp_mycl->var1 = 2;
    // populate sp_mycl->v_var4
    #pragma omp parallel for firstprivate(sp_mycl)
    for (auto ii = 0; ii<n;ii++)
    {
        sp_mycl->var2 = indata[ii];
        sp_mycl->calc();
        result[ii] = sp_mycl->var3;
    }

MyClass.h 与此类似

namespace MyNS
{
    extern "C" { double * fortran_dll_calc(int *num, double arrinput[],double arroutput[])} // subroutine in fortran dll
    class MyClass
    {
        double var1, var2, var3;
        std::vector<double> v_var4;
        void calc();
    }
}

和 MyClass.cpp

using namespace MyNS;
void MyClass::calc()
{
    int len = v_var4.size();
    double *test = new double[len];
    for (auto is = 0; is<len;is++)
        test[is] = v_var4[is];
    double fortran_result[10]; // output from fortran dll 
    fortran_dll_calc(len,test,fortran_result);
    for (int ir = 0;ir < 10;ir++)
        var3 += fortran_result[ir];
}

我将 MSVS 与 Intel parallel studio c++/fortran 编译器 2016 结合使用。

我希望 sp_mycl->var1 对所有线程具有相同的初始值,因此 sp_mycl 的 firstprivate。

openmp for 循环似乎在某处出错了,在调试时它有时似乎在 MyClass::calc() 中停止,有时已经在 sp_mycl->var2= indata [ii]。这是我使用一些 cout 输出发现的。

firstprivate 是否与 shared_ptr 一起用于我自己定义的对象? 我是初学者,因此可能会有很多错误和错误,欢迎对代码中的任何内容发表评论。

最佳答案

OpenMP 将为每个线程初始化私有(private)版本的 sp_mycl,如下所示:

   auto priv_sp_mycl = sp_mycl;

这是并行完成的,并调用复制构造函数,它最终需要更新 shared_ptr 的引用计数。但是,STL 中的 shared_ptr 实现不是线程安全的,因此事情开始出错。

但是,我不确定这是否是您想要的。为什么要让每个线程都指向同一个对象?这不会在您的程序中引入额外的竞争条件吗?此外,每个线程都将结果写入 result[n]...您是说 result[ii] 吗?

无论如何,我认为这就是您想要的:

MyNS::MyClass sp_mycl;
sp_mycl.var1 = 2;
// populate sp_mycl->v_var4
#pragma omp parallel for firstprivate(sp_mycl)
for (auto ii = 0; ii<n;ii++)
{
    sp_mycl.var2 = indata[ii];
    sp_mycl.calc();
    result[ii] = sp_mycl.var3;
}

关于由 小码哥发布于 2019-03-18 标签:c++openmpshared_ptrdatarace,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33963541/

相关文章:

c++ - 如何避免为 int 变量输入 char?

multithreading - gfortran openmp 无线程

c - 为什么多线程比单线程慢?

c++ - 无法调用模板构造函数

c++ - 构建自定义 boost 库

c++ - 有边界的strchr吗?

c++ - atof 只返回整数?

c++ - 减少 OpenMP 是否可以避免虚假共享?

c - openMp:需要并行化具有数据依赖性问题的循环

stack - openMP 中无限大小堆栈的行为