2017-08-09 7 views
1

J'ai écrit un petit programme pour tester le gain de performance d'OpenMP. Je compile en utilisant Microsoft Visual Studio.OpenMP provoque une erreur de compilation interne

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

c'est la fonction d'appel "checkPrime (i)" qui ressemble à ceci:

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

Je reçois maintenant un "C1001 Erreur: Une erreur interne est survenue dans le compilateur."

Suppression du #pragma omp parallèle pour résoudre ce problème. Alors, quel est le problème?

Merci à l'avance

Fölling

+0

La spécification OpenMP interdit aux threads d'avoir d'autres chemins de code de sortie que celui via la fin de la région parallèle. En d'autres termes, les instructions 'return' ou' goto' sur les étiquettes en dehors de la région parallèle ne sont pas autorisées. Le compilateur devrait émettre une erreur, mais l'implémentation OpenMP de Microsoft est ** très ** ancienne et non supportée et apparemment très cassée. –

+0

Faites le partage du travail sur la boucle externe plutôt que sur la boucle interne. Faites attention 'std :: vector' cependant. Soit réserver un morceau de mémoire à l'avance qui contiendra tous les nombres premiers ou remplir le fichier 'std :: vector' privé pour chaque thread, puis les rejoindre ensuite. –

Répondre

1

OpenMP est conçu pour engendrer de nombreux fils qui peuvent effectuer simultanément plusieurs opérations indépendantes. Dans votre cas, je crois que l'erreur est causée par le fait que beaucoup de threads sont engendrés, mais seulement certains d'entre eux sont prématurément terminés par l'instruction return false;. Au lieu de retourner immédiatement false, essayez de définir une variable booléenne:

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

De plus, notez que l'utilisation OpenMP exige que vous compilez avec des drapeaux supplémentaires. Vous le faites probablement déjà correctement si vous avez rencontré une erreur de compilation.

+0

Cela a fonctionné! Merci beaucoup pour cette aide – Folling