Je crée un vérificateur de base de nombres premiers, basé sur C – déterminer si un nombre est premier , mais en utilisant OpenMP.
int isPrime(int value) { omp_set_num_threads(4); #pragma omp parallel for for( int j = 2; j * j <= value; j++) { if ( value % j == 0) return 0; } return value; }
Lors de la compilation avec -fopenmp , la version 4.7.2 de GCC est erronée et indique invalid controlling predicate
par rapport à la boucle for.
Il semble que cette erreur soit causée par le carré j dans la boucle for. Est-il possible de contourner ce problème tout en obtenant le résultat souhaité de l’algorithme?
return
n’est pas autorisé à l’intérieur de la boucle car cela entraînerait une sortie avant les accolades.
Notez la définition donnée ci-dessous:
D’après la spécification OpenMP V2.5, 1.2.2 Terminologie du langage OpenMP, p2: 17-
bloc structuré – Pour C / C ++, une instruction exécutable, éventuellement composée, avec une seule entrée en haut et une seule sortie en bas.
Un bloc structuré commence par open {
et se termine par la fermeture }
. Le return
est contenu dans ces accolades, de sorte que ce programme viole également la définition OpenMP pour un bloc structuré, car il possède deux sorties (une au return
et une à la sortie à travers l’accolade).
OpenMP impose les cinq ressortingctions suivantes sur les boucles pouvant être threadées:
<
, <=
, >
ou >=
loop_invariant_integer <
ou <=
, la variable de boucle doit être incrémentée à chaque itération et inversement, si l'opération de comparaison est >
ou >=
, la variable de boucle doit être diminuée à chaque itération. Selon le standard OpenMP (§2.5.1, p.40), les formes acceptables du prédicat de contrôle de la boucle for
sont les suivantes:
Votre utilisation de j * j <= value
est une violation flagrante de cette exigence. Le raisonnement est qu'il nécessite que le compilateur émette un code qui calcule la racine carrée entière de la value
au moment de l'exécution, cette dernière n'étant pas définie pour certaines valeurs, en particulier les valeurs négatives.
Vous pouvez remplacer j * j <= value
par j <= sqrt_value
, où sqrt_value
est la racine carrée entière de value
, mais le problème serait d'avoir un autre chemin de sortie dans le bloc structuré à l'intérieur de la boucle. Malheureusement, il n’existe pas de solution simple dans ce cas, car OpenMP ne prend pas en charge la terminaison prématurée des boucles parallèles.