OpenACC Tutorial - Adding directives/fr: Difference between revisions

Jump to navigation Jump to search
Updating to match new version of source page
No edit summary
(Updating to match new version of source page)
Line 138: Line 138:
</syntaxhighlight>  
</syntaxhighlight>  


==== Développer avec OpenACC ====  
==== Building with OpenACC ====
Dans ce tutoriel, nous travaillons avec la version 16.3 des [http://www.pgroup.com/support/download_pgi2016.php?view=current compilateurs du Portland Group]. Nous utilisons l'option <tt>-ta</tt> (pour ''target accelerator'') pour porter le code sur les accélérateurs et la sous-option <tt>tesla:managed</tt> pour signifier au compilateur que les GPU Tesla sont la cible et que nous voulons utiliser une mémoire autogérée, ce qui simplifie le transfert de données dans les deux directions. Cette option ne sera pas utilisée dans un prochain exemple. Nous utilisons aussi l'option d'optimisation <tt>-fast</tt>.
 
En résultat, nous constatons que le compilateur n'a pu paralléliser les deux boucles;  nous verrons plus loin comment traiter ce cas.
<div class="mw-translate-fuzzy">
Choix du compilateur
</div>
|content=
En date de mai 2021, plusieurs compilateurs offraient les fonctionnalités OpenACC. Puisque cette technologie est principalement soutenue par [http://www.nvidia.com/content/global/global.php NVidia] et [http://www.cray.com/ Cray], les compilateurs de ces deux compagnies offrent le meilleur support pour OpenACC. Les fonctionnalités OpenACC des compilateurs de [https://gcc.gnu.org/wiki/OpenACC GNU] s'améliorent depuis la version 5.  
 
<div class="mw-translate-fuzzy">
Dans ce tutoriel, nous utilisons la version 20.7 des compilateurs NVidia pour le calcul de haute performance.
</div>
 
The NVidia compilers use the <tt>-ta</tt> (target accelerator) option to enable compilation for an accelerator. We use the sub-option <tt>tesla:managed</tt>, to tell the compiler that we want it compiled for Tesla GPUs, and we want to use managed memory. Managed memory simplifies the process of transferring data to and from the device. We will remove this option in a later example. We also use the option <tt>-fast</tt>, which is an optimization option.


{{Command
{{Command
Line 160: Line 170:
           34, Loop is parallelizable
           34, Loop is parallelizable
}}
}}
As we can see in the compiler output, the compiler could not parallelize the two loops. We will see in the following sections how to deal with this.  
As we can see in the compiler output, the compiler could not parallelize the two loops. We will see in the following sections how to deal with this.  
{{Callout
|title=Choix du compilateur
|content=
En date de mai 2021, plusieurs compilateurs offraient les fonctionnalités OpenACC. Puisque cette technologie est principalement soutenue par [http://www.nvidia.com/content/global/global.php NVidia] et [http://www.cray.com/ Cray], les compilateurs de ces deux compagnies offrent le meilleur support pour OpenACC. Les fonctionnalités OpenACC des compilateurs de [https://gcc.gnu.org/wiki/OpenACC GNU] s'améliorent depuis la version 5.
Dans ce tutoriel, nous utilisons la version 20.7 des compilateurs NVidia pour le calcul de haute performance.
}}


== Réparer les fausses dépendances de boucles ==
== Réparer les fausses dépendances de boucles ==
Même lorsque le programmeur sait qu'une boucle peut être parallélisée, il arrive que le compilateur ne le remarque pas. Un cas commun en C/C++ est connu sous le nom de [https://en.wikipedia.org/wiki/Pointer_aliasing ''pointer aliasing'']. Contrairement au Fortran, C/C++ ne possèdent pas comme tel de tableaux (''arrays''), mais plutôt des pointeurs. Le concept d'alias s'applique à deux pointeurs dirigés vers la même mémoire. Si le compilateur ne sait pas que des pointeurs ne sont pas des alias, il doit cependant le supposer. Dans l'exemple précédent, on voit clairement pourquoi le compilateur ne pouvait pas paralléliser la boucle. En supposant que les pointeurs sont identiques, il y a forcément dépendance des itérations de la boucle.  
Même lorsque le programmeur sait qu'une boucle peut être parallélisée, il arrive que le compilateur ne le remarque pas. Un cas commun en C/C++ est connu sous le nom de [https://en.wikipedia.org/wiki/Pointer_aliasing ''pointer aliasing'']. Contrairement au Fortran, C/C++ ne possèdent pas comme tel de tableaux (''arrays''), mais plutôt des pointeurs. Le concept d'alias s'applique à deux pointeurs dirigés vers la même mémoire. Si le compilateur ne sait pas que des pointeurs ne sont pas des alias, il doit cependant le supposer. Dans l'exemple précédent, on voit clairement pourquoi le compilateur ne pouvait pas paralléliser la boucle. En supposant que les pointeurs sont identiques, il y a forcément dépendance des itérations de la boucle.  


<div class="mw-translate-fuzzy">
===Mot-clé <tt>restrict</tt> ===  
===Mot-clé <tt>restrict</tt> ===  
Une des manières de dire au compilateur que les pointeurs '''ne sont pas''' des alias est d'utiliser  le mot-clé  <tt>restrict</tt>, introduit à cette fin dans C99.  Il n'y a toujours pas de manière standard pour ce faire en C++, mais chaque compilateur possède un mot-clé qui lui est propre. Dépendant du compilateur, on peut utiliser <tt>__restrict</tt> ou <tt>__restrict__</tt>. Les compilateurs du Portland Group utilisent <tt>__restrict</tt>. Pour savoir pourquoi il n'existe pas de standard en C++, consultez [http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3988.pdf ce document]. Ce concept est important pour OpenACC comme pour toute programmation C/C++, car les compilateurs peuvent effectuer plusieurs autres optimisations si les pointeurs ne sont pas des alias. Remarquez que le mot-clé se place '''après''' le pointeur puisque c'est à ce dernier qu'il se réfère, et non au type; autrement dit, la déclaration doit se lire <code>float * __restrict A;</code> plutôt que <code>float __restrict * A;</code>.  
Une des manières de dire au compilateur que les pointeurs '''ne sont pas''' des alias est d'utiliser  le mot-clé  <tt>restrict</tt>, introduit à cette fin dans C99.  Il n'y a toujours pas de manière standard pour ce faire en C++, mais chaque compilateur possède un mot-clé qui lui est propre. Dépendant du compilateur, on peut utiliser <tt>__restrict</tt> ou <tt>__restrict__</tt>. Les compilateurs du Portland Group utilisent <tt>__restrict</tt>. Pour savoir pourquoi il n'existe pas de standard en C++, consultez [http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3988.pdf ce document]. Ce concept est important pour OpenACC comme pour toute programmation C/C++, car les compilateurs peuvent effectuer plusieurs autres optimisations si les pointeurs ne sont pas des alias. Remarquez que le mot-clé se place '''après''' le pointeur puisque c'est à ce dernier qu'il se réfère, et non au type; autrement dit, la déclaration doit se lire <code>float * __restrict A;</code> plutôt que <code>float __restrict * A;</code>.
</div>




Line 182: Line 187:
En déclarant un pointeur comme étant ''restreint'', on s'assure qu'uniquement ce pointeur ou une valeur dérivée (comme <tt>ptr +1</tt>) pourra accéder à l'objet auquel il réfère, et ce pour la durée de vie du pointeur. Ceci est une garantie que le programmeur donne au compilateur;  si le programmeur manque à son obligation, le comportement n'est pas défini. Pour plus d'information, consultez l'article Wikipédia [https://en.wikipedia.org/wiki/Fstab restrict].  
En déclarant un pointeur comme étant ''restreint'', on s'assure qu'uniquement ce pointeur ou une valeur dérivée (comme <tt>ptr +1</tt>) pourra accéder à l'objet auquel il réfère, et ce pour la durée de vie du pointeur. Ceci est une garantie que le programmeur donne au compilateur;  si le programmeur manque à son obligation, le comportement n'est pas défini. Pour plus d'information, consultez l'article Wikipédia [https://en.wikipedia.org/wiki/Fstab restrict].  
}}
}}


=== Boucle avec clause <tt>independent</tt> ===  
=== Boucle avec clause <tt>independent</tt> ===  
38,760

edits

Navigation menu