今天把原来256*256*192网格的程序加密到512*256*192的时候,进入并行时出现了Segmentation fault错误:
./run.sh: line 13: 95841 Segmentation fault (core dumped) ./rib00
根据经验,首先检查ulimit,执行
ulimit -a
结果
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 2061342
max locked memory (kbytes, -l) 65536
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) unlimited
cpu time (seconds, -t) unlimited
max user processes (-u) 2061342
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
常见的堆栈stack已经是unlimited了,所以应该不是这里出问题。
返回去尝试,256*256*192能算,320*256*192也没报错,256*512*192报错了。于是排除是x方向网格设置的问题。应该是这里网格量太大内存爆了。会不会是这里哪个参数也要设成unlimited?
想起来学校超算是能跑的,于是查超算的ulimit设置:
core file size (blocks, -c) 4194304
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 513272
max locked memory (kbytes, -l) unlimited
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) unlimited
cpu time (seconds, -t) unlimited
max user processes (-u) 4096
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
只有这个max locked memory不一样。在服务器上尝试把这个改成unlimited,发现改不了,permition denied。于是搜这个东西要怎么改,查到说是要改一个什么参数然后要重启。服务器重启禁不住啊,于是作罢。
想想那还是去超算上跑吧。结果上超算是还是不能跑,一样的错误...
而且很久前算256*2048*128的都可以,那就应该是代码的问题了。
现在只能初步判断是在刚并行的位置附近的错误,具体哪里未知。于是搜怎么查错。首先要把core file size改成大值才能写入core文件:
ulimit -c unlimited
结果服务器上写不了core文件...不知道是什么问题
上超算试试。
首先编译时要加上这样,查错时才能查出是哪一行出错:
-g -traceback -check all
然后参照这个链接的查错方法:
gdb ./rib00 ./core.xxx
结果告诉我出错的地方是这一行:
365 !$omp parallel num_threads(num_omp) &
那就说是并行开始的这里就出错了,可是它错在哪里呢?莫非是OpenMP划分并行时有什么限制?内存不能过大?还是啥?
在这里:
看到说是
“编写linux多线程程序时,在线程内分配超过10M的栈空间后编译通过但运行时出现segmentation falut段错误,网上查了下线程的栈大小大概为8M ”
应该就是栈空间不够的问题。但是已经ulimit -s unlimited了,stack应该已经不限了,怎么还会超呢?
直到查到这个解释:
OpenMP专用阵列 - 分段错误:11 - VoidCChttp://cn.voidcc.com/question/p-gxhxdazk-bbp.html
有两种的堆栈大小限制。主线程的堆栈大小由Unix系统上的进程限制(使用
ulimit -s
来检查和修改此限制)或在Windows上的链接时固定(可执行文件的重新编译或二进制编辑是必要的,以便更改限制)。其他OpenMP线程的堆栈大小由像标准OMP_STACKSIZE
或实现特定的GOMP_STACKSIZE
(GNU/GCC OpenMP)和KMP_STACKSIZE
(英特尔OpenMP)的环境变量控制。
现在终于弄明白了,也就是说,ulimit -s unlimited只能使主线程的堆栈限制取消,但是OpenMP线程的堆栈限制需要通过更改环境变量OMP_STACKSIZE来设置。IBM官网上有具体修改的设置:
OMP_STACKSIZE - IBM Documentationhttps://www.ibm.com/docs/en/xl-c-aix/13.1.2?topic=openmp-omp-stacksize也就是,在./run.sh的命令中加入环境变量的设置(和设置OMP_THREADS数一样)
export OMP_STACKSIZE="1G"
这里把堆栈的限制设为了1G,对于512*256*192的网格是够了。
关于其他环境变量还可以看看这个链接: