ошибка сегментации openmp - странное поведение - PullRequest
1 голос
/ 22 июля 2011

Я новичок в c ++ и openmp в целом. У меня есть часть моей программы, которая вызывает странные ошибки сегментации (по крайней мере, для меня).

Это не происходит при использовании компилятора g ++, но происходит с компилятором intel, однако в последовательном соединении нет ошибок.

Он также не вызывает segfault при компиляции в другой системе (университет, HPC, компилятор Intel), но на моем ПК.

Также не происходит сегментация ошибки, когда присутствуют три конкретных оператора cout, однако, если какой-либо из них закомментирован, происходит ошибка сегмента. (Это то, что я нахожу странным)

Я новичок в использовании отладчика intel (idb), и я пока не знаю, как это правильно работать. Но мне удалось получить эту информацию:

Program received signal SIGSEGV
VLMsolver::iterateWake (this=<no value>) at /home/name/prog/src/vlmsolver.cpp:996
996     moveWakePoints();

Итак, я покажу метод moveWakePoints ниже и укажу на критические строки cout:

void VLMsolver::moveWakePoints() {

inFreeWakeStage =true;
int iw = 0;
std::vector<double> wV(3);
std::vector<double> bV(3);
for (int cl=0;cl<3;++cl) {
    wV[cl]=0;
    bV[cl]=0;
}

cout<<"thanks for helping"<<endl;

for (int b = 0;b < sNumberOfBlades;++b) {
    cout<<"b: "<<b<<endl;
    #pragma omp parallel for firstprivate(iw,b,bV,wV)
    for (int i = 0;i< iteration;++i) {
        iw = iteration -i - 1;
        for (int j = 0;j<numNodesY;++j) {
            cout<<"b: "<<b<<"a: "<<"a: "<<endl;
            double xp = wakes[b].x[iw*numNodesY+j];
            double yp = wakes[b].y[iw*numNodesY+j];
            double zp = wakes[b].z[iw*numNodesY+j];
            if ( (sFreeWake ==true && sFreezeAfter == 0) || ( sFreeWake==true && iw<((sFreezeAfter*2*M_PI)/(sTimeStep*sRotationRate)) && sRotationRate != 0  ) || ( sFreeWake==true && sRotationRate == 0 && iw<((sFreezeAfter*sChord)/(sTimeStep*sFreeStream)))) {
                if (iteration>1) { 
                    getWakeVelocity(xp, yp, zp, wV);
                }
                getBladeVelocity(xp, yp, zp, bV);
            } else {
                for (int cl=0;cl<3;++cl) {
                    wV[cl]=0;
                    bV[cl]=0;
                }
            }
            if (sRotationRate != 0) {
                double theta;
                theta = M_PI/2;
                double radius = sqrt(pow(yp,2) + pow(zp,2));
                wakes[b].yTemp[(iw+1)*numNodesY+j] = cos(theta - sTimeStep*sRotationRate)*radius;
                wakes[b].zTemp[(iw+1)*numNodesY+j] = sin(theta - sTimeStep*sRotationRate)*radius;
                wakes[b].xTemp[(iw+1)*numNodesY+j] = xp + sFreeStream*sTimeStep;
            } else { 
                std::vector<double> fS(3);
                getFreeStreamVelocity(xp, yp, zp, fS);
                wakes[b].xTemp[(iw+1)*numNodesY+j] = xp + fS[0] * sTimeStep;
                wakes[b].yTemp[(iw+1)*numNodesY+j] = yp + fS[1] * sTimeStep;
                wakes[b].zTemp[(iw+1)*numNodesY+j] = zp + fS[2] * sTimeStep;
            }
            wakes[b].xTemp[(iw+1)*numNodesY+j] = wakes[b].xTemp[(iw+1)*numNodesY+j] + (wV[0]+bV[0])*sTimeStep;
            wakes[b].yTemp[(iw+1)*numNodesY+j] = wakes[b].yTemp[(iw+1)*numNodesY+j] + (wV[1]+bV[1])*sTimeStep;
            wakes[b].zTemp[(iw+1)*numNodesY+j] = wakes[b].zTemp[(iw+1)*numNodesY+j] + (wV[2]+bV[2])*sTimeStep;

        }  // along the numnodesy
    }  // along the iterations i
    if (sBladeSymmetry) {
        break;
    }
}

}

Три строки cout вверху - это то, что я добавил, и обнаружил, что программа работала, когда я это сделал.

Например, в третьей строке cout, если я изменю ее на:

cout<<"b: "<<"a: "<<"a: "<<endl;

я получаю сигфо, или если я изменю его на:

cout<<"b: "<<b<<endl; 

, у меня тоже есть ошибка.

Спасибо за чтение, я ценю любые идеи.

Ответы [ 2 ]

2 голосов
/ 17 августа 2011

Как уже говорилось в предыдущем ответе, вы можете попытаться использовать Valgrind, чтобы обнаружить, где ваша память повреждена. Просто скомпилируйте свой двоичный файл с помощью "-g -O0" и затем выполните:

valgrind --tool=memcheck --leak-check=full <binary> <arguments>

Если вам повезет, вы получите точную строку и столбец в исходном коде, где произошло нарушение памяти.

Тот факт, что segfault исчезает, когда добавляются некоторые операторы "printf", действительно не странен. Добавляя эти операторы, вы изменяете часть памяти, которой владеет программа. Если по какой-либо причине вы пишете в неправильном месте внутри разрешенной части памяти, то ошибка не возникнет.

Вы можете обратиться к этому pdf-файлу (раздел «Методы отладки / за пределами») для более широкого объяснения темы:

Летняя школа параллельных вычислений

Надеюсь, я вам помог: -)

1 голос
/ 22 июля 2011
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...