2017-08-09 221 views
1

我编写了一个小程序来测试OpenMP的性能增益。 我使用Microsoft Visual Studio进行编译。OpenMP导致内部编译器错误

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。那么交易是什么?预先

Folling

+0

OpenMP规范禁止线程具有任何其他退出代码路径,而不是通过并行区域末尾的代码路径。换句话说,不允许在并行区域之外的'return'语句或'goto'标签。编译器应该发出一个错误,但是微软的OpenMP实现**非常**旧,不受支持,显然非常破碎。 –

+0

在外层循环而不是内层循环上进行工作共享。不过要小心'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,您需要与其他标志编译。如果遇到编译器错误,您可能已经正确执行此操作。

+0

工作正常! 非常感谢您的帮助 – Folling