OpenACC Tutorial - Profiling/fr: Difference between revisions

no edit summary
(Updating to match new version of source page)
No edit summary
 
(31 intermediate revisions by one other user not shown)
Line 9: Line 9:
* savoir concentrer vos efforts et réécrire les routines qui exigent beaucoup de temps
* savoir concentrer vos efforts et réécrire les routines qui exigent beaucoup de temps
}}
}}
<div class="mw-translate-fuzzy">
== Profiler du code  ==
== Profiler du code  ==
Pourquoi auriez-vous besoin de profiler du code? Parce que c'est la seule façon de comprendre
Pourquoi auriez-vous besoin de profiler du code? Parce que c'est la seule façon de comprendre
* comment le temps est employé aux points critiques (''hotspots''),
* comment le temps est employé aux points critiques (''hotspots''),
* comprendre la performance du code,
* comprendre la performance du code,
* savoir comment mieux employer votre temps.
* savoir comment mieux employer votre temps de développement.
</div>


<div class="mw-translate-fuzzy">
Pourquoi est-ce important de connaitre les points critiques dans le code?  
Pourquoi est-ce important de connaitre les points critiques dans le code?  
D'après la loi d'Amdahl, paralléliser les routines qui exigent le plus de temps d'exécution (les points critiques) produit le plus d'impact.
D'après [https://en.wikipedia.org/wiki/Amdahl%27s_law la loi d'Amdahl], paralléliser les routines qui exigent le plus de temps d'exécution (les points critiques) produit le plus d'impact.
</div>


<div class="mw-translate-fuzzy">
== Préparer le code pour l'exercice ==
== Préparer le code pour l'exercice ==
Pour notre exemple, nous utilisons du code provenant de  [https://github.com/calculquebec/cq-formation-openacc ces dépôts]. Téléchargez les fichiers et utilisez les répertoires ''cpp'' ou ''f90''. Le but de l'exercice est de compiler et lier le code et d'obtenir un exécutable que nous profilerons.
Pour l'exemple suivant, nous utilisons du code provenant de  [https://github.com/calculquebec/cq-formation-ce dépôt de données Git].
</div>
[https://github.com/calculquebec/cq-formation-openacc/archive/refs/heads/main.zip Téléchargez et faites l'extraction du paquet] et positionnez-vous dans le répertoire <code>cpp</code> ou <code>f90</code>. Le but de cet exemple est de compiler et lier le code pour obtenir un exécutable pour en profiler le code source avec un profileur.


{{Callout
{{Callout
|title=Choix du compilateur
|title=Choix du compilateur
|content=
|content=
<div class="mw-translate-fuzzy">
Mis de l'avant par [https://www.cray.com/ Cray] et par [https://www.nvidia.com NVIDIA] via sa division
En date de mai 2016, relativement peu de compilateurs offraient les fonctionnalités d'OpenACC. Les plus avancés en ce sens sont les compilateurs du [http://www.pgroup.com/ Portland Group] de [http://www.nvidia.com/content/global/global.php NVidia] et ceux de [http://www.cray.com/ Cray]. Pour ce est qui de [https://gcc.gnu.org/wiki/OpenACC GNU], l'implémentation d'OpenACC dans la version 5 était expérimentale et devrait être complète dans la version 6.
[https://www.pgroup.com/support/release_archive.php Portland Group] jusqu'en 2020 puis via  [https://developer.nvidia.com/hpc-sdk sa trousse HPC SDK], ceux deux types de compilateurs offrent le support le plus avancé pour OpenACC.
</div>


As for the [https://gcc.gnu.org/wiki/OpenACC GNU compilers], since GCC version 6, the support for OpenACC 2.x kept improving.
Quant aux [https://gcc.gnu.org/wiki/OpenACC compilateurs GNU], le support pour OpenACC 2.x continue de s'améliorer depuis la version 6 de GCC.
As of July 2022, GCC versions 10, 11 and 12 support OpenACC version 2.6.
En date de juillet 2022, les versions GCC 10, 11 et 12 supportent la version 2.6 d'OpenACC.


<div class="mw-translate-fuzzy">
Dans ce tutoriel, nous utilisons la version 22.7 de [https://developer.nvidia.com/nvidia-hpc-sdk-releases NVIDIA HPC SDK]. Notez que les compilateurs NVIDIA sont gratuits à des fins de recherche universitaire.  
Dans ce tutoriel, nous utilisons la version 16.3 des [http://www.pgroup.com/support/download_pgi2016.php?view=current compilateurs du Portland Group] qui sont gratuits pour des fins de recherche universitaire.
</div>
}}
}}


Line 59: Line 51:
}}
}}


<div class="mw-translate-fuzzy">
Une fois l'exécutable <code>cg.x</code> créé, nous allons profiler son code source. Le profileur mesure les appels des fonctions en exécutant et en surveillant ce programme.
Une fois l'exécutable créé, nous allons profiler le code.
'''Important :''' Cet exécutable utilise environ 3Go de mémoire et un cœur CPU presque à 100&nbsp;%. '''L'environnement de test devrait donc avoir 4Go de mémoire disponible et au moins deux (2) cœurs CPU'''.
</div>


{{Callout
{{Callout
|title=Choix du profileur
|title=Choix du profileur
|content=
|content=
<div class="mw-translate-fuzzy">
Dans ce tutoriel, nous utilisons deux profileurs&nbsp;:  
Dans ce tutoriel, nous utilisons plusieurs des profileurs suivants&nbsp;:  
 
* PGPROF : outil simple mais puissant pour l'analyse de programmes parallèles écrits avec OpenMP, OpenACC ou [https://fr.wikipedia.org/wiki/Compute_Unified_Device_Architecture CUDA]; rappelons que PGPROF est gratuit pour des fins de recherche universitaire.
* '''[https://docs.nvidia.com/cuda/profiler-users-guide/ <code>nvprof</code> de NVIDIA]''' , un profileur en ligne de commande capable d'analyser des codes non GPU
* NVVP (NVIDIA Visual Profiler) : outil d'analyse multiplateforme pour des programmes écrits avec OpenACC et CUDA C/C++.
* '''[[OpenACC_Tutorial_-_Adding_directives#NVIDIA_Visual_Profiler|<code>nvvp</code> (NVIDIA Visual Profiler) ]]''', un outil d'analyse multiplateforme pour des programmes écrits avec OpenACC et CUDA C/C++.
* NVPROF : version ligne de commande du NVIDIA Visual Profiler.
Puisque <code>cg.x</code> que nous avons construit n'utilise pas encore le GPU, nous allons commencer l'analyse avec le profileur <code>nvprof</code>.
</div>
}}
}}


<div class="mw-translate-fuzzy">
=== Profileur en ligne de commande NVIDIA <code>nvprof</code> ===
<br />
Dans sa trousse de développement pour le calcul de haute performance, NVIDIA fournit habituellement <code>nvprof</code>, mais la version qu'il faut utiliser sur nos grappes est incluse dans un module CUDA.
<br />
<br />
<br />
<br />
=== NVPROF ligne de commande ===
La version ligne de commande de NVPROF est semblable à GPU prof.
</div>
{{Command
{{Command
|module load cuda/11.7
|module load cuda/11.7
}}
}}


To profile a pure CPU executable, we need to add the arguments <code>--cpu-profiling on</code> to the command line:
Pour profiler un exécutable CPU pur, nous devons ajouter les arguments <code>--cpu-profiling on</code> à la ligne de commande.
{{Command
{{Command
|nvprof --cpu-profiling on ./cg.x  
|nvprof --cpu-profiling on ./cg.x  
Line 109: Line 92:
======== Data collected at 100Hz frequency
======== Data collected at 100Hz frequency
}}
}}
From the above output, the <code>matvec()</code> function is responsible for 83.5% of the execution time, and this function call can be found in the <code>main()</code> function.
Dans le résultat, la fonction <code>matvec()</code> utilise 83.5&nbsp;% du temps d'exécution; son appel se trouve dans la fonction <code>main()</code>.


<div class="mw-translate-fuzzy">
==Renseignements sur le compilateur==
==Renseignements sur le compilateur==
Avant de travailler sur la routine, nous devons comprendre ce que fait le compilateur; posons-nous les questions suivantes&nbsp;:
Avant de travailler sur la routine, nous devons comprendre ce que fait le compilateur; posons-nous les questions suivantes&nbsp;:
* Quelles sont les optimisations qui ont été appliquées?  
* Quelles sont les optimisations qui ont été automatiquement appliquées par le compilateur?  
* Qu'est-ce qui a empêché d'optimiser davantage?
* Qu'est-ce qui a empêché d'optimiser davantage?
* La performance serait-elle affectée par les petites modifications?
* La performance serait-elle affectée par les petites modifications?
</div>


<div class="mw-translate-fuzzy">
Le compilateur NVIDIA offre l'indicateur <code>-Minfo</code> avec les options suivantes&nbsp;:
Le compilateur PGI offre l'indicateur '''-Minfo'''  avec les options suivantes&nbsp;:
* <code>all</code>, pour imprimer presque tous les types d'information, incluant
* accel – liste des opérations du compilateur relativement à l'accélérateur
** <code>accel</code> pour les opérations du compilateur en rapport avec l'accélérateur
* all – résultats en sortie du compilateur
** <code>inline</code> pour l'information sur les fonctions extraites et alignées
* intensity – renseignements sur l'intensité de la boucle
** <code>loop,mp,par,stdpar,vect</code> pour les renseignements sur l'optimisation et la vectorisation des boucles
* ccff – ajout de renseignements aux fichiers objet pour utilisation future
* <code>intensity</code>, pour imprimer l'information sur l'intensité des boucles
</div>
* (aucune option) produit le même résultat que l'option  <code>all</code>, mais sans l'information fournie par <code>inline</code>.


<div class="mw-translate-fuzzy">
== Obtenir les renseignements sur le compilateur  ==
== Obtenir les renseignements sur le compilateur  ==
* Éditez le Makefile.
* Modifiez le Makefile.
CXX=nvc++
  CXX=nvc++
CXXFLAGS=-fast -Minfo=all,intensity,ccff
  CXXFLAGS=-fast -Minfo=all,intensity
LDFLAGS=${CXXFLAGS}
  LDFLAGS=${CXXFLAGS}
 
* Effectuez un nouveau build.
* Effectuez un nouveau build.
</div>
* Rebuild
{{Command
{{Command
|make clean; make
|make clean; make
Line 262: Line 240:
}}
}}


<div class="mw-translate-fuzzy">
== Interpréter le résultat ==
== Intensité computationnelle ==
L'''intensité computationnelle'' d'une boucle représente la quantité de travail accompli par la boucle en fonction des opérations effectuées en mémoire, soit
L'intensité computationnelle d'une boucle représente la quantité de travail accompli par la boucle en fonction des opérations effectuées en mémoire.
</div>


<div class="mw-translate-fuzzy">
<math>\mbox{intensité computationnelle} = \frac{\mbox{opérations de calcul}}{\mbox{opérations en mémoire}}</math>
'''intensité computationnelle = opérations de calcul / opérations en mémoire'''
</div>


<div class="mw-translate-fuzzy">
Dans le résultat, une valeur supérieure à 1 pour <code>Intensity</code> indique que la boucle serait bien exécutée sur un processeur graphique (GPU).
Une valeur de 1 ou plus indique que la boucle serait bien exécutée sur un processeur graphique (GPU).
</div>


<div class="mw-translate-fuzzy">
== Comprendre le code  ==
== Comprendre le code  ==
Regardons attentivement le code suivant de <code>matrix_functions.h</code>&nbsp;:
Regardons attentivement la boucle principale  de
</div>
[https://github.com/calculquebec/cq-formation-openacc/blob/main/cpp/matrix_functions.h#L29 la fonction <code>matvec()</code> implémentée dans <code>matrix_functions.h</code>]:
<syntaxhighlight lang="cpp" line start="29" highlight="1,5,10,12">
<syntaxhighlight lang="cpp" line start="29" highlight="1,5,10,12">
   for(int i=0;i<num_rows;i++) {
   for(int i=0;i<num_rows;i++) {
Line 293: Line 264:
   }
   }
</syntaxhighlight>  
</syntaxhighlight>  
<div class="mw-translate-fuzzy">
On trouvera les dépendances de données en se posant les questions suivantes&nbsp;:
On trouvera les dépendances de données en se posant les questions suivantes&nbsp;:
* Une itération en affecte-t-elle d'autres?
* Une itération en affecte-t-elle d'autres?
* Les itérations lisent-elles ou écrivent-elles à des endroits différents du même tableau?
** par exemple, quand une  '''[https://fr.wikipedia.org/wiki/Suite_de_Fibonacci suite de Fibonacci]''' est générée, chaque nouvelle valeur dépend des deux valeurs qui la précèdent. Il est donc très difficile, sinon impossible, d'implémenter un parallélisme efficace.
* Est-ce que sum est une dépendance? Non, c'est une réduction.
* L'accumulation des valeurs dans <code>sum</code> est-elle une dépendance?
</div>
** Non, c'est une''' [https://en.wikipedia.org/wiki/Reduction_operator réduction]'''! Et les compilateurs modernes optimisent bien ce genre de réduction.  
* Est-ce que les itérations de boucle écrivent et lisent dans les mêmes vecteurs de sorte que les valeurs sont utilisées ou écrasées par d'autres itérations?
** Heureusement, ceci ne se produit pas dans le code ci-dessus.


Maintenant que le code est analysé, nous pouvons ajouter des directives au compilateur.
Maintenant que le code est analysé, nous pouvons ajouter des directives au compilateur.


[[OpenACC Tutorial - Introduction/fr|<- Page précédente, ''Introduction'']] | [[OpenACC Tutorial/fr|^- Retour au début du tutoriel]] | [[OpenACC Tutorial - Adding directives/fr|Page suivante, ''Ajouter des directives'' ->]]
[[OpenACC Tutorial - Introduction/fr|<- Page précédente, ''Introduction'']] | [[OpenACC Tutorial/fr|^- Retour au début du tutoriel]] | [[OpenACC Tutorial - Adding directives/fr|Page suivante, ''Ajouter des directives'' ->]]
Bureaucrats, cc_docs_admin, cc_staff, rsnt_translations
2,837

edits