[英]c++ openmp shared_ptr datarace
我有一个C ++程序,在其中尝试在for循环上使用openmp。 for循环与shared_ptr一起用于我自己的类,该类又调用另一个dll。 我收到错误消息:
表7.当前指针和in_use_count不一致。
该代码看起来像这样。
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的sp_mycl
。
openmp for循环似乎在某处出错,并且在调试时有时似乎停止在MyClass::calc()
,有时已经在sp_mycl->var2= indata[ii]
。 我已经发现了一些使用cout
输出的内容。
firstprivate
是否与shared_ptr
用于我自己定义的对象? 我是一个初学者,因此可能会有很多错误和错误,对代码中的任何注释都应赞赏。
OpenMP将为每个线程初始化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;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.