====== Parallélisation automatique avec Intel compiler====== Les compilateurs Intel ® C++ et Fortran ont la capacité d'analyser le flux de données dans les boucles d'un programme afin de déterminer si leurs itérations peuvent être exécutées en parallèle. La parallélisation automatique peut réduire le temps d'exécution sur des architectures multi-coeurs. Le compilateur aide le programmeur à : * Rechercher des boucles qui sont de bons candidats pour une exécution en parallèle * Effectuer une analyse de flux de données pour vérifier une exécution parallèle Pour activer la parallélisation automatique, il suffit de rajouter l'option -parallel. Toutefois, le succès de la parallélisation est soumise dépend de certains critères : - Le nombre d'itérations doit être connu avant d'entrer dans la boucle. - Le corps de la boucle ne doit pas contenir de branchements (goto,...) vers l'intérieur ou l'extérieur de la boucle. - Les itérations de la boucle doivent être indépendantes : absence de dépendances entre les itérations Lorsque le compilateur est incapable de paralléliser automatiquement les boucles complexes, OpenMP est la solution préférée. Dans ce cas, c'est au programmeur de s'assurer que les boucles peuvent être parallélisées sans problème. ===== Exemple ===== Prenons un exemple en fortran : PROGRAM TEST PARAMETER (N=10000000) REAL A, C(N) DO I = 1, N A = 2 * I - 1 C(I) = SQRT(A) ENDDO PRINT*, N, C(1), C(N) END L'analyse de flux de données confirme que la boucle ne contient pas de dépendances de données. Le compilateur génère un code qui distribue les itérations sur l'ensemble de coeurs (threads) disponibles à l'exécution. On peut spécifier le nombre de threads à utiliser à la ''OpenMP'' on exportant la variable d'environnement : $OMP_NUM_THREADS. Par exemple : $ export $OMP_NUM_THREADS=8 Utilise 8 threads (coeurs) pour l'exécution. **Compilation :** $ ifort -parallel test.f90 -o test test.f90(4): (col. 3) remark: LOOP WAS AUTO-PARALLELIZED Le compilateur est capable de générer un rapport sur les boucles qui ne pouvait pas paralléliser en utilisant l'option : -par-report3 Voici un exemple : void add (int k, float *a, float *b) { for (int i = 1; i < 10000; i++) a[i] = a[i+k] + b[i]; } icc -parallel -par-report3 test.c -o test procedure: add test.c(7): (col. 1) remark: parallel dependence: assumed ANTI dependence between a line 7 and a line 7. flow data dependence assumed ... test.c(7): (col. 1) remark: parallel dependence: assumed FLOW dependence between a line 7 and b line 7. **Analyse** Parce que le compilateur ne connaît pas la valeur de ''k'', il suppose que les itérations dépendent les unes des autres, comme par exemple si ''k'' est égal à ''-1''. Cependant, le programmeur connaît mieux son application (par exemple, ''k'' toujours supérieure à 10000), et peut dans ce cas aider le compilateur à paralléliser la boucle en lui donnant une indication supplémentaire, en insérant la clause : #pragma parallel en entrée de la boucle : void add (int k, float *a, float *b) { #pragma parallel for (int i = 1; i < 10000; i++) a[i] = a[i+k] + b[i]; } $ icc -parallel -par-report3 test.c -o test procedure: add test.c(6): (col. 1) remark: LOOP WAS AUTO-PARALLELIZED. ===== Voir aussi ===== Parallélisation avec [[OpenMP]] ====== Liens ====== http://software.intel.com/en-us/articles/intel-guide-for-developing-multithreaded-applications/