2

I wrote a little program to test the performance gain of OpenMP. I compile using 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";
}

this is the function calling "checkPrime(i)" which looks like this:

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;        
}

I am now getting a "C1001 Error : An internal error has occured in the compiler."

Removing the #pragma omp parallel for solves this problem. So what's the deal?

Thanks in advance

Folling

2
  • 1
    The OpenMP specification forbids the threads to have any other exit code paths than the one via the end of the parallel region. In other words, return statements or goto to labels outside the parallel region are not allowed. The compiler should issue an error, but Microsoft's OpenMP implementation is very old and unsupported and apparently very broken. Commented Aug 9, 2017 at 19:48
  • Do the work sharing on the outer loop rather than the inner loop. Be careful std::vector though. Either reserve a chunk of memory ahead of time that will contain all the primes or fill private std::vector for each thread and then join them afterwards. Commented Aug 10, 2017 at 8:29

1 Answer 1

2

OpenMP is designed to spawn numerous threads which can perform multiple independent operations simultaneously. In your case, I believe the error is caused by the fact that many threads are spawned, but only some of them are prematurely terminated by the return false; statement. Instead of immediately returning false, try setting a boolean variable:

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;        
}

Additionally, note that using OpenMP requires that you compile with additional flags. You're probably already doing this correctly if you ran into a compiler error.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.