У меня есть программа на C++, где я пытаюсь использовать openmp в цикле for. Цикл for работает с shared_ptr в моем собственном классе, который, в свою очередь, вызывает другую dll. Я получаю ошибки:C++ openmp shared_ptr datarace
Таблица 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];
}
я использую МСВС с компилятором Intel parallel studio C++/fortran 2016.
Я хочу, чтобы sp_mycl->var1
имел одинаковое значение для всех потоков, поэтому firstprivate для sp_mycl
.
Путь к openmp для петли, кажется, где-то идет не так, и когда отладка иногда кажется остановленной внутри MyClass::calc()
, а иногда уже на sp_mycl->var2= indata[ii]
. Это я обнаружил, используя некоторые выходы cout
.
Является ли firstprivate
, работающим с shared_ptr
собственными определенными объектами? Я новичок, поэтому может быть много ошибок и ошибок, любой комментарий на что-либо в коде оценивается.
Большое спасибо @ simple01. Единственное, что мне интересно, это если опасно ставить много предметов в стек? –
Каждый поток имеет отдельный стек ... и вы помещаете только один объект MyClass, каждый из которых равен '3 * sizeof (double) + sizeof (std :: vector)', который составляет около 200 байт (помните std :: вектор выполняет выделение памяти в куче, а не в стеке). Я думаю, что использование стека не является проблемой. – simpel01