|
|
Présentation du site Cours Erlang Articles Projets Autour d'Erlang-fr Liens English Area Miroir: Documentation Erlang Miroir: Archives Erlang/OTP Recherche ![]()
|
Hipe: La compilation native de programmes ErlangLa nouvelle version de l'environnement de développement Erlang inclus désormais Hipe. Hipe (High-Performance Erlang) est à l'origine un projet de l'Université d'Uppsala ayant pour objectif l'amélioration des performances des programmes Erlang. Hipe est un compilateur générant du code natif sur Solaris Sparc et Linux x86. Téléchargement d'Erlang R8Le version R8B d'Erlang/OTP est sortie le 17 octobre 2001. Elle est disponible sur le site officiel d'Erlang, Erlang.org, et peut-être téléchargé à l'adresse suivante: http://www.erlang.org/download.html CompilationLa compilation sous Linux nécessite de lancer les commandes suivantes dans le répertoire racine de l'archive téléchargée, après sa décompression: ./configure --enable-hipe make make installLa dernière commande doit être lancée avec les droits d'administrateur de la machine (root). Le principeIl faut savoir que le mécanisme de compilation native ne génère pas de fichier directement exécutable, mais intégre simplement le code exécutable dans le fichier .beam qui contient le pseudo-code. Cette approche peut sembler étrange, mais elle est en fait très cohérente. Elle permet de distribuer uniquement les fichiers beam tout en conservant le caractère multiplateforme. Seuls les plate-formes pour lequel le code natif peut être exécuté l'utiliseront. Les autres plateformes utiliseront le pseudo-code contenu dans le fichier beam. L'autre avantage majeur est que le mécanisme de fonctionnement des applications existantes n'est pas perturbé. Grâce à ce mécanisme, on peut même compiler certains modules, voire certaines fonctions dans ces modules, qui collaboreront avec des modules interprétés. Les premiers testsNous allons prendre un exemple extrêment simple pour bien comprendre le mécanisme de compilation. Nous allons compiler le programme suivant:
-module(test).
-export([go/0]).
go()->
io:format("~p~n", [calendar:universal_time()]).
Il existe deux méthodes traditionnelles pour compiler ce programme en pseudo-code:
Nous disposons des mêmes possibilités pour la compilation native:
Quelques optionsLa compilation native accepte quelques options permettant d'optimiser plus ou moins le code produit (o1, o2, o3) ou bien d'obtenir des informations sur le processus de compilation (verbose). Voici un exemple d'utilisation de ces options:
Erlang (BEAM) emulator version 5.1 [source] [hipe]
Eshell V5.1 (abort with ^G)
1> c(test, [native, {hipe,[o3,verbose]}]).
[HiPE Compiler (v 1.0.0)] Options: [{'O',3},
icode_rename,
{regalloc,coalescing},
use_indexing,
icode_prop,
remove_comments,
trim_frame,
rtl_prop_2,
verbose].
[HiPE Compiler (v 1.0.0)] Compiling {test,go,0} in 0.32 s
[HiPE Compiler (v 1.0.0)] Compiling {test,module_info,0} in 0.02 s
[HiPE Compiler (v 1.0.0)] Compiling {test,module_info,1} in 0.00 s
[HiPE Compiler (v 1.0.0)] Compiled test in 0.34 s
[HiPE Compiler (v 1.0.0)] Assembling test in 0.05 s
{ok,test}
Les performancesQuels gains de performance apporte la compilation native ? Sur le module test.erl, l'exécution de la fonction go() prend 261 micro-secondes en mode interprété:
Erlang (BEAM) emulator version 5.1 [source] [hipe]
Eshell V5.1 (abort with ^G)
1> m(test).
Module test compiled: Date: November 3 2001, Time: 11.03
Compiler options: [v3]
Object file: /home/mikl/erlang/perso/workshop/test.beam
Exports:
go/0
module_info/0
module_info/1
ok
6> timer:tc(test,go,[]).
{{2001,11,3},{11,4,21}}
{261,ok}
Le temps d'exécution est identique sur la version compilée:
Erlang (BEAM) emulator version 5.1 [source] [hipe]
Eshell V5.1 (abort with ^G)
1> m(test).
Module test compiled: Date: November 3 2001, Time: 11.06
Compiler options: [v3,native]
Object file: /home/mikl/erlang/perso/workshop/test.beam
Exports:
go/0
module_info/0
module_info/1
module_info/0
module_info/1
ok
6> timer:tc(test,go,[]).
{{2001,11,3},{11,9,34}}
{242,ok}
Ce test n'est toutefois absoluement pas signicatif, car le temps d'exécution total est beaucoup trop faible pour être représentatif. La moindre variation d'activité de la machine peut faire changer le résultat du simple au double. Nous allons donc faire le test sur le calcul de la fonction d'ackermann, tel qu'il est réalisé dans le benchmark «shoutout»:
%%% -*- mode: erlang -*-
%%% $Id: ackermann.erlang,v 1.6 2000/10/07 08:41:43 doug Exp $
%%% http://www.bagley.org/~doug/shootout/
-module(ackermann).
-export([main/1]).
main() -> main(['1']).
main([Arg]) ->
Num = list_to_integer(atom_to_list(Arg)),
io:fwrite("Ack(3,~w): ~w\n", [Num, ack(3, Num)]),
ok.
%%halt(0).
ack(0, N) -> N+1;
ack(M, 0) -> ack(M-1, 1);
ack(M, N) -> ack(M-1, ack(M, N-1)).
Le temps d'exécution de la fonction en mode interprété est de 7,8 secondes (paramètre 10):
Erlang (BEAM) emulator version 5.1 [source] [hipe]
Eshell V5.1 (abort with ^G)
1> c(ackermann).
./ackermann.erl:18: Warning: function main/0 is unused
{ok,ackermann}
2> timer:tc(ackermann,main,[['10']]).
Ack(3,10): 8189
{7783410,ok}
Le temps d'exécution est réduit de 3,6 fois avec la compilation native:
Erlang (BEAM) emulator version 5.1 [source] [hipe]
Eshell V5.1 (abort with ^G)
1> c(ackermann,[native,{hipe,o3}]).
./ackermann.erl:18: Warning: function main/0 is unused
{ok,ackermann}
2> timer:tc(ackermann,main,[['10']]).
Ack(3,10): 8189
{2146980,ok}
La compilation native permet donc d'améliorer les performances d'un code Erlang intensif en traitement. D'autres tests monte cependant que l'amélioration est négligeable sur du code utilisant des échanges sockets par exemple. C'est le cas par exemple avec le code Echo Client/serveur du benchmark shoutout. Les effets de bordLa compilation native induit cependant quelques effets de bord. Les informations de déboguage sur du code natif sont quasi inexistante. Je recommande donc de ne pas utiliser la compilation native en phase de développement, mais pour le déploiement du logiciel. D'autre part, si vous utilisez les informations de débogguage pour certains mécanismes de tolérance aux pannes dans vos programmes, la compilation native peut avoir des conséquences sur le fonctionnement même du programme. Je recommande donc de passer votre jeu de test sur le code compilé nativement avant tout déploiement. Historique de ce documentVersion initiale (2001-11-03): Mickaël Rémond. |
Pour tout commentaire: erlang@erlang-fr.org
Dernière modification: 2005-11-11 18:48:4