RHEL5上的短c openmp程序随机崩溃
Random crashes with short c openmp program on RHEL5
我真的很困惑你们。
下面是一个小型、独立、简单的40行程序,它计算一堆数字的部分和,并定期(但随机)崩溃我正在使用的分布式内存集群上的节点。如果我生成50个运行此代码的PBS作业,其中0到4个作业的节点将崩溃。它每次都会发生在主循环的不同重复上,每次都发生在不同的节点上,没有明显的模式。节点只是在ganglia报告中"向下",我不能对它们进行ssh("没有到主机的路由")。如果我没有提交作业,而是ssh到其中一个节点上并在那里运行我的程序,如果我运气不好,它崩溃了,那么我就不再看到文本,然后看到那个节点在ganglia上死了。
该程序使用openmp进行线程处理,只有在派生出大量线程(如12个)时才会发生崩溃。
它杀死的集群是一个RHEL 5集群,其节点具有2个6核x5650处理器:
[jamelang@hooke~]$tail/etc/redhat发布
Red Hat Enterprise Linux Server 5.7版(Tikanga)
我尝试启用核心转储ulimit -c unlimited
,但没有显示任何文件。这是代码,带有注释:
#include <cstdlib>
#include <cstdio>
#include <omp.h>
int main() {
const unsigned int numberOfThreads = 12;
const unsigned int numberOfPartialSums = 30000;
const unsigned int numbersPerPartialSum = 40;
// make some numbers
srand(0); // every instance of program should get same results
const unsigned int totalNumbersToSum = numbersPerPartialSum * numberOfPartialSums;
double * inputData = new double[totalNumbersToSum];
for (unsigned int index = 0; index < totalNumbersToSum; ++index) {
inputData[index] = rand()/double(RAND_MAX);
}
omp_set_num_threads(numberOfThreads);
// prepare a place to dump output
double * partialSums = new double[numberOfPartialSums];
// do the following algorithm many times to induce a problem
for (unsigned int repeatIndex = 0; repeatIndex < 100000; ++repeatIndex) {
if (repeatIndex % 1000 == 0) {
printf("Absurd testing is on repeat %06un", repeatIndex);
}
#pragma omp parallel for
for (unsigned int partialSumIndex = 0; partialSumIndex < numberOfPartialSums;
++partialSumIndex) {
// get this partial sum's limits
const unsigned int beginIndex = numbersPerPartialSum * partialSumIndex;
const unsigned int endIndex = numbersPerPartialSum * (partialSumIndex + 1);
// we just sum the 40 numbers, can't get much simpler
double sumOfNumbers = 0;
for (unsigned int index = beginIndex; index < endIndex; ++index) {
// only reading, thread-safe
sumOfNumbers += inputData[index];
}
// writing to non-overlapping indices (guaranteed by omp),
// should be thread-safe.
// at worst we would have false sharing, but that would just affect
// performance, not throw sigabrts.
partialSums[partialSumIndex] = sumOfNumbers;
}
}
delete[] inputData;
delete[] partialSums;
return 0;
}
我用以下代码编译它:
/home/jamelang/gcc-4.8.1/bin/g++-O3-墙-fopenmp Killer.cc-o Killer
它似乎与正确的共享对象链接:
[jamelang@hooke Killer]$ ldd Killer
linux-vdso.so.1 => (0x00007fffc0599000)
libstdc++.so.6 => /home/jamelang/gcc-4.8.1/lib64/libstdc++.so.6 (0x00002b155b636000)
libm.so.6 => /lib64/libm.so.6 (0x0000003293600000)
libgomp.so.1 => /home/jamelang/gcc-4.8.1/lib64/libgomp.so.1 (0x00002b155b983000)
libgcc_s.so.1 => /home/jamelang/gcc-4.8.1/lib64/libgcc_s.so.1 (0x00002b155bb92000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x0000003293a00000)
libc.so.6 => /lib64/libc.so.6 (0x0000003292e00000)
/lib64/ld-linux-x86-64.so.2 (0x0000003292a00000)
librt.so.1 => /lib64/librt.so.1 (0x0000003298600000)
一些注意事项:
1.在带有gcc 4.7的osx-lion上,这段代码会抛出一个SIGABRT,类似于这个问题:为什么这段代码用openMP给出SIGABRT?。使用gcc 4.8似乎可以解决OSX上的问题。但是,在RHEL5机器上使用gcc 4.8并不能解决这个问题。RHEL5计算机的GLIBC版本是2.5,而且百胜似乎没有提供更高版本,所以管理员们坚持使用2.5。
2.如果我定义了一个SIGABRT信号处理程序,它不会在RHEL5机器上捕获问题,但它会在带有gcc47的OSX上捕获问题。
3.我认为omp子句中不应该共享任何变量,因为它们都可以有私有副本,但将它们添加为共享并不会改变行为
4.无论使用何种优化级别,节点都会被杀死
5.即使我从gdb中运行程序(即在pbs文件中放入"gdb-batch-x gdbCommand Killer"),节点也会被杀死,其中"gdbCommand"是一个只有一行的文件:"run"
6.这个例子在每次重复时都会产生线程。一种策略是制作一个包含重复循环的并行块,以防止这种情况发生。然而,这对我没有帮助——这个例子只是一个更大的研究代码的代表,我不能在其中使用这种策略。
我已经无计可施了,在我的最后一根稻草上,在我智穷的时候,我已经做好了拔头发的准备,等等。有人有什么建议或想法吗?
您正在尝试对嵌套的for循环进行并行化,在这种情况下,您需要使内部循环中的变量私有,这样每个线程都有自己的变量。可以使用private
子句来完成,如下例所示。
#pragma omp parallel for private(j)
for (i = 0; i < height; i++)
for (j = 0; j < width; j++)
c[i][j] = 2;
在您的情况下,index
和sumOfNumbers
需要是私有的。
- 该程序将.csv文件中的一系列单词放入数组中,然后随机生成句子.但它不起作用
- DoModal 主应用程序随机返回 -1 代码
- 如何随机化程序的窗口标题?
- 定义指针随机崩溃该程序
- 如何在C 程序中随机做一个
- 程序有效,但在 20-30 秒后随机关闭
- 使用OpenSSL和锁随机崩溃的多线程程序
- 字符串更改程序输出随机字符
- C++初始化指针会使应用程序随机崩溃
- PRNG程序故障.无法输入随机数量的选择,并且将始终从PRNG中回答2
- 编写一个程序,该程序在0-99范围内生成10000个随机整数,并从随机数据中产生直方图
- 由于多个线程中的 free() 调用,程序随机崩溃
- 当Windows XP(32位,SP3)播放声音时,随机应用程序暂停半秒钟
- 随机打印程序,尽管 sleep() 功能,一次打印多个输出
- 似乎是随机程序在完成C++时失败
- C++程序无缘无故地随机冻结
- 有什么方法可以制作一个程序,随机选择10-20个字符串并用C++向用户显示
- 关于在omnetpp.ini中将两个不同的应用程序随机分配到50个节点
- RHEL5上的短c openmp程序随机崩溃
- 写函数的基本问题.程序随机跳到最后