Sophie

Sophie

distrib > Mandriva > 9.0 > i586 > by-pkgid > 0d5cd12c82d627a82c59047e1ba7b8a9 > files > 90

howto-html-fr-9.0-0.2mdk.noarch.rpm

<HTML>
<HEAD>
<TITLE>Avez-vous besoin de l'assembleur?</TITLE>
</HEAD>
<BODY>
<A NAME="doyouneedasm"></A> <H1>2. <A NAME="s2"></A>Avez-vous besoin de l'assembleur?</H1>
<P>
<A HREF="Assembly-HOWTO.html#toc2">Contenu de cette section</A></P>

<P>Je ne veux en aucun cas jouer les emp&ecirc;cheurs-de-tourner-en-rond,
mais voici quelques conseils issus d'une exp&eacute;rience gagn&eacute;e &agrave; la dure.</P>
<P></P>
<P></P>
<P></P>
<H2>2.1 <A NAME="ss2.1"></A> Le Pour et le Contre</H2>

<P></P>
<P></P>
<P></P>
<H3>Les avantages de l'assembleur</H3>

<P></P>
<P>L'assembleur peut vous permettre de r&eacute;aliser des op&eacute;rations tr&egrave;s bas niveau:
<UL>
<LI>vous pouvez acc&eacute;der aux registres et aux ports d'entr&eacute;es/sorties
sp&eacute;cifiques &agrave; votre machine;</LI>
<LI>vous pouvez parfaitement contr&ocirc;ler le comportemant du code dans
des sections critiques o&ugrave; pourraient sinon advenir un blocage du processeur
ou des p&eacute;riph&eacute;riques;</LI>
<LI>vous pouvez sortir des conventions de production de code
de votre compilateur habituel;
ce qui peut vous permettre d'effectuer certaines optimisations
(par exemple contourner les r&egrave;gles d'allocation m&eacute;moire,
g&eacute;rer manuellement le cours de l'&eacute;x&eacute;cution, etc.);</LI>
<LI>acc&eacute;der &agrave; des modes de programmation non courants de votre processeur 
(par exemple du code 16 bits pour l'amor&ccedil;age ou l'interfa&ccedil;age avec le BIOS,
sur les p&eacute;c&eacute;s Intel);</LI>
<LI>vous pouvez construire des interfaces entre des fragments de codes
utilisant des conventions incompatibles (c'est-&agrave;-dire produit par
des compilateurs diff&eacute;rents ou s&eacute;par&eacute;s par une interface bas-niveau);</LI>
<LI>vous pouvez g&eacute;n&eacute;rer un code assez rapide pour les boucles importantes
pour pallier aux d&eacute;fauts d'un compilateur qui ne sait les optimiser
(mais bon, il existe des compilateurs optimisateurs librement
disponibles!);</LI>
<LI>vous pouvez g&eacute;n&eacute;rer du code optimis&eacute; "&agrave; la main" qui 
est plus parfaitement r&egrave;gl&eacute; pour votre configuration mat&eacute;rielle pr&eacute;cise,
m&ecirc;me s'il ne l'est pour aucune autre configuration;</LI>
<LI>vous pouvez &eacute;crire du code pour le compilateur optimisateur
de votre nouveau langage.
(c'est l&agrave; une activit&eacute; &agrave; laquelle peu se livrent, et encore, rarement.)</LI>
</UL>
</P>
<P></P>
<P></P>
<P></P>
<H3>Les inconv&eacute;nients de l'assembleur</H3>

<P></P>
<P>L'assembleur est un langage tr&egrave;s bas niveau
(le langage du plus bas niveau qui soit au dessus du codage &agrave; la main
de motifs d'instructions en binaire). En cons&eacute;quence:
<UL>
<LI>l'&eacute;criture de code en est longue et ennuyeuse;</LI>
<LI>les bogues apparaissent ais&eacute;ment;</LI>
<LI>les bogues sont difficiles &agrave; rep&eacute;rer et supprimer;</LI>
<LI>il est difficile de comprendre et de modifier du code
(la maintenance est tr&egrave;s compliqu&eacute;e);</LI>
<LI>le r&eacute;sultat est extr&ecirc;mement peu portable vers une autre architecture,
existante ou future;</LI>
<LI>votre code ne sera optimis&eacute; que une certaine impl&eacute;mentation d'une
m&ecirc;me architecture: ainsi, parmi les plates-formes compatibles Intel,
chaque r&eacute;alisation d'un processeur et de ses variantes
(largeur du bus, vitesse et taille relatives des CPU/caches/RAM/Bus/disques,
pr&eacute;sence ou non d'un coprocesseur arithm&eacute;tique, et d'extensions MMX ou autres)
implique des techniques d'optimisations parfois radicalement diff&eacute;rentes.
Ainsi diff&egrave;rent grandement les processeurs d&eacute;j&agrave; existant et leurs variations:
Intel 386, 486, Pentium, PPro, Pentium II; Cyrix 5x86, 6x86; AMD K5, K6.
Et ce n'est s&ucirc;rement pas termin&eacute;: de nouveaux mod&egrave;les apparaissent
continuellement, et cette liste m&ecirc;me sera rapidement d&eacute;pass&eacute;e,
sans parler du code ``optimis&eacute;'' qui aura &eacute;t&eacute; &eacute;crit pour l'un
quelconque des processeurs ci-dessus.</LI>
<LI>le code peut &eacute;galement ne pas &ecirc;tre portable entre diff&eacute;rents
syst&egrave;mes d'exploitation sur la m&ecirc;me architecture,
par manque d'outils adapt&eacute;s (GAS semble fonctionner sur toutes
les plates-formes; NASM semble fonctionner ou &ecirc;tre facilement adaptable
sur toutes les plates-formes compatibles Intel);</LI>
<LI>un temps incroyable de programmation sera perdu sur de menus d&eacute;tails,
plut&ocirc;t que d'&ecirc;tre efficacement utilis&eacute; pour la conception et le
choix des algorithmes utilis&eacute;s, alors que ces derniers sont connus
pour &ecirc;tre la source de la majeure partie des gains en vitesse d'un programme.
Par exemple, un grand temps peut &ecirc;tre pass&eacute; &agrave; grapiller quelques cycles en
&eacute;crivant des routines rapides de manipulation de cha&icirc;nes ou de listes,
alors qu'un remplacement de la structure de donn&eacute;es &agrave; un haut niveau,
par des arbres &eacute;quilibr&eacute;s et/ou des tables de hachage permettraient
imm&eacute;diatement un grand gain en vitesse, et une parall&eacute;lisation ais&eacute;e,
de fa&ccedil;on portable permettant un entretien facile.</LI>
<LI>une petite modification dans la conception algorithmique d'un programme
an&eacute;antit la validit&eacute; du code assembleur si patiemment &eacute;labor&eacute;,
r&eacute;duisant les d&eacute;veloppeurs au dilemne de sacrifier le fruit de leur labeur,
ou de s'encha&icirc;ner &agrave; une conception algorithmique obsol&egrave;te.</LI>
<LI>pour des programmes qui fait des choses non point trop &eacute;loign&eacute;es
de ce que font les benchmarks standards,
les compilateurs/optimiseurs commerciaux produisent du code
plus rapide que le code assembleur &eacute;crit &agrave; la main
(c'est moins vrai sur les architectures x86 que sur les architectures RISC,
et sans doute moins vrai encore pour les compilateurs librement disponible.
Toujours est-il que pour du code C typique, GCC est plus qu'honorable).</LI>
<LI>Quoi qu'il en soit, ains le dit le saige John Levine,
mod&eacute;rateur de comp.compilers, "les compilateurs rendent ais&eacute;e
l'utilisation de structures de donn&eacute;es complexes;
ils ne s'arr&ecirc;tent pas, morts d'ennui, &agrave; mi-chemin du travail,
et produisent du code de qualit&eacute; tout &agrave; fait satisfaisante".
Ils permettent &eacute;galement de propager <EM>correctement</EM> les transformations
du code &agrave; travers l'ensemble du programme, aussi h&eacute;naurme soit-il,
et peuvent optimiser le code par-del&agrave; les fronti&egrave;res entre proc&eacute;dures
ou entre modules.</LI>
</UL>
</P>
<P></P>
<P></P>
<P></P>
<H3>Affirmation</H3>

<P></P>
<P>En pesant le pour et le contre, on peut conclure
que si l'assembleur est parfois n&eacute;cessaire,
et peut m&ecirc;me &ecirc;tre utile dans certains cas o&ugrave; il ne l'est pas,
il vaut mieux:
<UL>
<LI>minimiser l'utilisation de code &eacute;crit en assembleur;</LI>
<LI>encapsuler ce code dans des interfaces bien d&eacute;finies;</LI>
<LI>engendrer automatiquement le code assembleur
&agrave; partir de motifs &eacute;crits dans un langage plus de haut niveau que l'assembleur
(par exemple, des macros contenant de l'assembleur en-ligne, avec GCC);</LI>
<LI>utiliser des outils automatiques pour transformer ces programmes
en code assembleur;</LI>
<LI>faire en sorte que le code soit optimis&eacute;, si possible;</LI>
<LI>utiliser toutes les techniques pr&eacute;c&eacute;dentes &agrave; la fois,
c'est-&agrave;-dire &eacute;crire ou &eacute;tendre la passe d'optimisation d'un compilateur.</LI>
</UL>
</P>
<P>M&ecirc;me dans les cas o&ugrave; l'assembleur est n&eacute;cessaire
(par exemple lors de d&eacute;veloppement d'un syst&egrave;me d'exploitation),
ce n'est qu'&agrave; petite dose, et sans infirmer les principes ci-dessus.</P>
<P>Consultez &agrave; ce sujet les sources du noyau de Linux:
vous verrez qu'il s'y trouve juste le peu qu'il faut d'assembleur,
ce qui permet d'avoir un syst&egrave;me d'exploitation rapide, fiable,
portable et d'entretien facile.
M&ecirc;me un jeu tr&egrave;s c&eacute;l&egrave;bre comme DOOM a &eacute;t&eacute; en sa plus grande partie &eacute;crit en C,
avec une toute petite routine d'affichage en assembleur pour acc&eacute;l&eacute;rer un peu.</P>
<P></P>

<H2>2.2 <A NAME="ss2.2"></A> Comment ne pas utiliser l'assembleur</H2>

<P></P>
<P></P>
<H3>M&eacute;thode g&eacute;n&eacute;rale pour obtenir du code efficace</H3>

<P></P>
<P>Comme le dit Charles Fiterman dans comp.compilers &agrave; propos
de la diff&eacute;rence entre code &eacute;crit par l'homme ou la machine,</P>
<P>``L'homme devrait toujours gagner, et voici pourquoi:
<UL>
<LI>Premi&egrave;rement, l'homme &eacute;crit tout dans un langage de haut nivrau.</LI>
<LI>Deuxi&egrave;mement, il mesure les temps d'&eacute;x&eacute;cution (profiling)
pour d&eacute;terminer les endroits o&ugrave; le programme passe la majeure partie du temps.</LI>
<LI>Troisi&egrave;mement, il demande au compilateur d'engendrer le code assembleur
produit pour ces petites sections de code.</LI>
<LI>Enfin, il effectue &agrave; la main modifications et r&eacute;glages,
&agrave; la recherche des petites am&eacute;liorations possibles par rapport au
code engendr&eacute; par la machine.</LI>
</UL>

L'homme gagne parce qu'il peut utiliser la machine.''</P>
<P></P>
<P></P>
<H3>Langages avec des compilateurs optimisateurs</H3>

<P></P>
<P>Des langages comme ObjectiveCAML, SML, CommonLISP, Scheme,
ADA, Pascal, C, C++, parmi tant d'autres,
ont tous des compilateurs optimiseurs librement disponibles,
qui optimiseront le gros de vos programmes,
et produiront souvent du code meilleur que de l'assembleur fait-main,
m&ecirc;me pour des boucles serr&eacute;es,
tout en vous permettant de vous concentrer sur des d&eacute;tails haut niveau,
et sans vous interdire de gagner par la m&eacute;thode pr&eacute;c&eacute;dente
quelques pourcents de performance suppl&eacute;mentaire,
une fois la phase de conception g&eacute;n&eacute;rale termin&eacute;e.
Bien s&ucirc;r, il existe &eacute;galement des compilateurs optimiseurs commerciaux
pour la plupart de ces langages.</P>
<P>Certains langages ont des compilateurs qui produisent du code C
qui peut ensuite &ecirc;tre optimis&eacute; par un compilateur C.
C'est le cas des langages LISP, Scheme, Perl, ainsi que de nombreux autres.
La vitesse des programmes obtenus est toute &agrave; fait satisfaisante.</P>
<P></P>
<P></P>
<H3>Proc&eacute;dure g&eacute;n&eacute;rale &agrave; suivre pour acc&eacute;lerer votre code</H3>

<P></P>
<P>Pour acc&eacute;l&eacute;rer votre code, vous ne devriez traiter que
les portions d'un programme qu'un outil de mesure de temps d'&eacute;x&eacute;cution
(profiler) aura identifi&eacute; comme &eacute;tant un goulot d'&eacute;tranglement
pour la performance de votre programme.</P>
<P>Ainsi, si vous identifiez une partie du code comme &eacute;tant trop lente,
vous devriez
<UL>
<LI>d'abord essayer d'utiliser un meilleur algorithme;</LI>
<LI>essayer de la compiler au lieu de l'interpr&eacute;ter;</LI>
<LI>essayer d'activer les bonnes options d'optimisation
de votre compilateur;</LI>
<LI>donner au compilateur des indices d'optimisation
(d&eacute;clarations de typage en LISP; utilisation des extensions GNU avec GCC;
la plupart des compilos fourmillent d'options);</LI>
<LI>enfin de compte seulement, se mettre &agrave; l'assembleur si n&eacute;cessaire.</LI>
</UL>
</P>
<P>Enfin, avant d'en venir &agrave; cette derni&egrave;re option,
vous devriez inspecter le code g&eacute;n&eacute;r&eacute;
pour v&eacute;rifier que le probl&egrave;me vient effectivement
d'une mauvaise g&eacute;n&eacute;ration de code,
car il se peut fort bien que ce ne soit pas le cas:
le code produit par le compilateur pourrait &ecirc;tre meilleur
que celui que vous auriez &eacute;crit, en particulier sur les architectures
modernes &agrave; pipelines multiples!
Il se peut que les portions les plus lentes de votre programme
le soit pour des raisons intrins&egrave;ques.
Les plus gros probl&egrave;mes sur les architectures modernes &agrave; processeur rapide
sont dues aux d&eacute;lais introduits par les acc&egrave;s m&eacute;moires, manqu&eacute;s des caches
et TLB, fautes de page;
l'optimisation des registres devient vaine,
et il vaut mieux repenser les structures de donn&eacute;es et l'encha&icirc;nement
des routines pour obtenir une meilleur localit&eacute; des acc&egrave;s m&eacute;moire.
Il est possible qu'une approche compl&egrave;tement diff&eacute;rente du probl&egrave;me
soit alors utile.</P>
<P></P>
<P></P>
<H3>Inspection du code produit par le compilateur</H3>

<P>Il existe de nombreuses raisons pour vouloir regarder le code assembleur
produit par le compilateur. Voici ce que vous pourrez faire avec ce code:
<UL>
<LI>v&eacute;rifier si le code produit peut ou non &ecirc;tre am&eacute;liorer avec
du code assembleur &eacute;crit &agrave; la main
(ou par un r&eacute;glage diff&eacute;rent des options du compilateur);</LI>
<LI>quand c'est le cas, commencer &agrave; partir de code automatiquement engendr&eacute;
et le modifier plut&ocirc;t que de repartir de z&eacute;ro;</LI>
<LI>plus g&eacute;n&eacute;ralement, utilisez le code produit comme
des scions &agrave; greffer, ce qui &agrave; tout le moins vous laisse permet
d'avoir gratuitement tout le code d'interfa&ccedil;age avec le monde ext&eacute;rieur.</LI>
<LI>rep&eacute;rer des bogues &eacute;ventuels dus au compilateur lui-m&ecirc;me
(esp&eacute;rons-le tr&egrave;s rare, quitte &agrave; se restreindre &agrave; des versions
``stables'' du compilo).</LI>
</UL>
</P>
<P>La mani&egrave;re standard d'obtenir le code assembleur g&eacute;n&eacute;r&eacute; est d'appeller
le compilateur avec l'option <CODE>-S</CODE>.
Cela fonctionne avec la plupart des compilateur Unix y compris
le compilateur GNU C (GCC); mais &agrave; vous de voir dans votre cas.
Pour ce qui est de GCC, il produira un code un peu plus compr&eacute;hensible
avec l'option <CODE>-fverbose-asm</CODE>. Bien sur, si vous souhaitez obtenir
du code assembleur optimis&eacute;, n'oubliez pas d'ajouter les options et indices
d'optimisation appropri&eacute;es!</P>
<P></P>
<P></P>
<P></P>

<HR>
<P>
Chapitre <A HREF="Assembly-HOWTO-3.html">suivant</A>,
Chapitre <A HREF="Assembly-HOWTO-1.html">Pr&eacute;c&eacute;dent</A>
<P>
Table des mati&egrave;res de <A HREF="Assembly-HOWTO.html#toc2">ce chapitre</A>,
 <A HREF="Assembly-HOWTO.html#toc">Table des mati&egrave;res</A> g&eacute;n&eacute;rale</P>
<P>
<A HREF="Assembly-HOWTO.html">D&eacute;but</A> du document,
 <A HREF="#0"> D&eacute;but de ce chapitre</A></P>
</BODY>
</HTML>