Openmp分割错误-奇怪的行为
openmp segmentation fault - strange behaviour
我对c++和openmp还是个新手。我的程序中有一部分在奇怪的情况下导致分段错误(至少对我来说很奇怪)。
在使用g++编译器时不会出现错误,但在使用intel编译器时会出现错误,但是在串行中没有错误。
在不同的系统(大学hpc,英特尔编译器)上编译时也不会出现段错误,但在我的PC上。
当出现三个特定的cout语句时,它也不会出现段错误,但是如果其中任何一个语句被注释掉,则会发生段错误。(这就是我觉得奇怪的地方)
我是使用英特尔调试器(idb)的新手,我不知道如何正确工作。但我确实设法从中得到了这个信息:
Program received signal SIGSEGV
VLMsolver::iterateWake (this=<no value>) at /home/name/prog/src/vlmsolver.cpp:996
996 moveWakePoints();
那么我将在下面展示moveWakePoints方法,并指出关键的计数行:
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<<"b: "<<"a: "<<"a: "<<endl;
我得到段错误,或者如果我把它改为:
cout<<"b: "<<b<<endl;
,我也得到了段错误
谢谢你的阅读,谢谢你的建议。
正如前面的答案所述,您可以尝试使用Valgrind来检测内存损坏的位置。用"-g - 0"编译二进制文件,然后运行:
valgrind --tool=memcheck --leak-check=full <binary> <arguments>
如果幸运的话,您将获得源代码中发生内存冲突的确切行和列。
当添加一些"printf"语句时,段错误消失的事实确实并不奇怪。添加这些语句,就是在修改程序所拥有的内存部分。如果碰巧在允许的内存部分内的错误位置写入,则不会发生段错误。
您可以参考这个pdf("调试技术/越界"一节)以获得关于该主题的更广泛的解释:
Summer School of Parallel Computing
希望我对你有所帮助:-)
-
尝试增加堆栈大小,http://software.intel.com/sites/products/documentation/hpc/composerxe/en-us/cpp/lin/optaps/common/optaps_par_var.htm
-
尝试valgrind
-
尝试调试器
- C++映射分割错误(核心转储)
- 由cin中的字符串中未捕获空白引起的分割错误
- 删除映射和分割错误中的一个过去结束元素
- 在指向函数中读取变量时出现分割错误
- 在链表中的第 n 位插入显示分割错误
- 较高值 n 的分割错误(例如 n=999997)
- 尝试通过memcpy复制大尺寸浮点向量时的分割错误
- 分割错误:向量中的擦除功能
- 向量向量的分割错误
- 我在C++中编写了一个方法来打印树类的预序,但它显示了分割错误
- C ++分割错误,为什么使用"long long"我没有得到答案?
- 在尝试使用递归查找集合子集的总数时,我遇到了分割错误
- 分割错误 11:尝试使用 cin 输入 B[1] 时
- 集合布局上的 Qt 分割错误
- 高达20亿的筛子会产生分割错误
- 对向量使用推回函数时的分割错误
- 绘制精灵会导致分割错误
- 将矢量的整数内容打印为字符串会导致分割错误
- 分割错误:使用向量时为 11 c++
- 结构的分割错误错误