[英]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.