简体   繁体   English

标签c ++ openmp shared_ptr datarace

[英]c++ openmp shared_ptr datarace

I have a c++ program where I try to use openmp on a for loop. 我有一个C ++程序,在其中尝试在for循环上使用openmp。 The for loop works with an shared_ptr to my own class that in turn calls another dll. for循环与shared_ptr一起用于我自己的类,该类又调用另一个dll。 I get errors: 我收到错误消息:

Table 7. Current pointer and in_use_count are inconsistent. 表7.当前指针和in_use_count不一致。

The code looks something like this.. 该代码看起来像这样。

    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;
    }

and MyClass.h looks similar to this 和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();
    }
}

and MyClass.cpp 和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];
}

I use MSVS with Intel parallel studio c++/fortran compiler 2016. 我将MSVS与Intel Parallel Studio C ++ / Fortran编译器2016一起使用。

I want the sp_mycl->var1 to have the same inital value for all threads, hence the firstprivate for sp_mycl . 我希望sp_mycl->var1对于所有线程都具有相同的初始值,因此是sp_mycl的sp_mycl

The openmp for loop seems to be going wrong somewhere, and when debugging it sometimes appear to stop inside MyClass::calc() , and sometimes already at sp_mycl->var2= indata[ii] . openmp for循环似乎在某处出错,并且在调试时有时似乎停止在MyClass::calc() ,有时已经在sp_mycl->var2= indata[ii] This much I have found out using some cout outputs. 我已经发现了一些使用cout输出的内容。

Is the firstprivate working with shared_ptr to my own defined objects? firstprivate是否与shared_ptr用于我自己定义的对象? I am a beginner thus, there might be many mistakes and errors, any comment on anything in the code is appreciated. 我是一个初学者,因此可能会有很多错误和错误,对代码中的任何注释都应赞赏。

OpenMP is going to initialize the private version of sp_mycl for each of the thread as follows: OpenMP将为每个线程初始化sp_mycl的私有版本,如下所示:

   auto priv_sp_mycl = sp_mycl;

This is done in parallel and invokes the copy constructor which needs finally needs to update the reference counting for the shared_ptr . 这是并行完成的,并调用复制构造函数,该复制构造函数最终需要更新shared_ptr的引用计数。 However, shared_ptr implementation in STL is not thread-safe so there is where things starts to goes wrong. 但是,STL中的shared_ptr实现不是线程安全的,因此有些地方开始出错。

However, I am not sure this is what you want. 但是,我不确定这是否是您想要的。 Why do you want to have every thread pointing to the same object? 为什么要让每个线程都指向同一个对象? Wouldn't that introduce an additional race condition into your program? 那不会在程序中引入额外的竞争条件吗? Also each thread is writing the result into result[n] ... did you mean result[ii] ? 而且每个线程都将结果写入result[n] ……您是说result[ii]吗?

Anyway, I think this is what you want: 无论如何,我认为这是您想要的:

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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM