OpenMP 导致内部编译器错误
Posted
技术标签:
【中文标题】OpenMP 导致内部编译器错误【英文标题】:OpenMP causes internal compiler error 【发布时间】:2017-08-09 16:40:34 【问题描述】:我编写了一个小程序来测试 OpenMP 的性能提升。 我使用 Microsoft Visual Studio 进行编译。
void findAllPrimesUntilX()
for (int i = 2; i <= upToXthPrimes; i++)
if (i % 500 == 0) std::cout << "First " << i * 500 << "primes have been checked\n";
if (checkPrime(i)) primes.push_back(i);
std::cout << "All primes have been calculated!\n";
这是调用“checkPrime(i)”的函数,如下所示:
bool checkPrime(int n)
if (n == 2) return true;
if (n < 2 || n % 2 == 0) return false;
#pragma omp parallel for
for (int i = 3; i <= static_cast<int>(sqrt(n)); i += 2)
if (n % i == 0) return false;
return true;
我现在收到“C1001 错误:编译器发生内部错误。”
删除#pragma omp parallel for 解决了这个问题。那么有什么关系呢?
提前致谢
以下
【问题讨论】:
OpenMP 规范禁止线程拥有除并行区域末端之外的任何其他退出代码路径。换句话说,return
语句或goto
到并行区域之外的标签是不允许的。编译器应该会发出错误,但 Microsoft 的 OpenMP 实现非常旧且不受支持,而且显然非常损坏。
在外循环而不是内循环上共享工作。不过要小心std::vector
。要么提前保留一块包含所有素数的内存,要么为每个线程填充私有std::vector
,然后再加入它们。
【参考方案1】:
OpenMP 旨在生成大量线程,这些线程可以同时执行多个独立操作。在您的情况下,我认为该错误是由于产生了许多线程,但只有其中一些线程被 return false;
语句提前终止。不要立即返回false
,而是尝试设置一个布尔变量:
bool checkPrime(int n)
if (n == 2) return true;
if (n < 2 || n % 2 == 0) return false;
bool prime = true;
#pragma omp parallel for
for (int i = 3; i <= static_cast<int>(sqrt(n)); i += 2)
if (n % i == 0) prime = false;
return prime;
另外,请注意,使用 OpenMP 需要使用附加标志进行编译。如果遇到编译器错误,您可能已经正确执行此操作。
【讨论】:
以上是关于OpenMP 导致内部编译器错误的主要内容,如果未能解决你的问题,请参考以下文章
GCC 8.1.0/MinGW64 编译的 OpenMP 程序崩溃寻找 cygwin.s?
在 Oracle 11g2 XE 中编译 PL/SQL 函数有时会导致 ORA-00600:内部错误
BFD:矮人错误:使用 GNU 4.7.2 使用 HPCToolKit 分析 openmp 程序时