Les options de gcc et leurs effets

Rappel sur les benchs

Un bench mesure toujours un paramètre très précis de la machine. Il est claire que dans la vrai vie ça n'est pas aussi simple, donc prenez avec précaution les conclusions qui vont suivre. Ce n'est pas parce-qu'un bench dit qu'une option de compilation multiplie par deux la vitesse d'une fonction qu'il suffit de recompiler tous ses programmes de la vraie vie pour constater un gain en vitesse d'un facteur de deux. Si c'était si simple, ça se saurait :) .

Le choix du programme test

Avant de se lancer dans des tests compliqués, il faut choisir un programme test et s'y tenir. Pour ma part j'ai réecrit un petit programme de calcul de l'ensemble de Mandelbrot. On peut trouver d'autres programmes pratiques sur le site ftp de l'Inria.

Donc voici mon programme de test :

mandelbrot.c

/*
  Programme de bench
  calcul de l'ensemble de Mandelbrot

  Emmanuel DUMAS (emmanuel.dumas@free.fr)
  25/10/2001

*/

/* il y a volontairement aucun include,
 cela simplifie la compilation*/

#define XMIN -2.5
#define XMAX 1.5
#define YMIN -1.5
#define YMAX 1.5

#define NMAX 1024
#define SEUIL 4.0

#define LX 1024
#define LY 768

#ifndef NUMBER
#define NUMBER double
#endif


/* Fonction de calcul de l'ensemble de Mandelbrot

rappel du principe :

on calcule la suite zn+1=zn²+z0
si la suite diverge, le point n'appartient pas à l'ensemble
sinon il appartient

*/

int mandelpoint(NUMBER z0_r,
		NUMBER z0_i,
		int nmax)
{
  int cp=0;
  NUMBER zn_r,zn_i,a,b;

  /* initialisation */
  zn_r=z0_r;
  zn_i=z0_i;
  a=zn_r*zn_r;
  b=zn_i*zn_i;
  /* et on fait tourner le tout */
  while ( (cp<nmax) &&( (a+b) < SEUIL ) )
    {
      zn_i=2.0*zn_r*zn_i+z0_i;
      zn_r=a-b+z0_r;
      a=zn_r*zn_r;
      b=zn_i*zn_i;
      cp++;
    }
  return cp;
}

/* Pour obtenir une image on calcul cette fct
   pour tout un plan */
void mandelbrot(const NUMBER xmin,
		const NUMBER xmax,
		const NUMBER ymin,
		const NUMBER ymax,
		const int lx,
		const int ly,
		const int nmax,
		int *res)
{
  int x,y;

  for(x=0;x<lx;x++)
    for(y=0;y<ly;y++)
      {
	NUMBER z0_r,z0_i;
	/* calcul de z0 */
	z0_r=xmin+(xmax-xmin)*x/lx;
	z0_i=ymin+(ymax-ymin)*y/ly;

	/* on sauve le résultat */
	res[x+y*lx]=mandelpoint(z0_r,z0_i,nmax);
      }
}


main()
{
  int i;

  /* On fait le calcul 10 fois pour moyenner le résultat */
  for(i=0;i<10;i++)
    {
      int res[LX*LY];
      mandelbrot(XMIN,XMAX,YMIN,YMAX,LX,LY,NMAX,res);
    }

  return 0;

}

Première expérimentation

Ce petit programme se compile très facilement. On suppose que le code source se trouve dans le fichier mandelbrot.c, la ligne de commande standard pour le compiler est :

Ready  cc mandelbrot.c -o mandelbrot

Ensuite pour l'executer, il suffit de tapper :

Ready ./mandelbrot
Ready

Seulement il ne faut oublier qu'arrivé à ce stade pour l'instant, il ne se passe pas grand chose.

Pour aller plus loin il faut connaitre la commande time. Les plus vifs des lecteurs auront déjà regarder ce que dit le man sur ce sujet, pour les autres, je vais vous donner le résultat sur ma machine, au moins le début pour savoir de quoi il s'agit:

Ready man time

TIME(1)                                                   TIME(1)

NAME
       time - time a simple command or give resource usage

SYNOPSIS
       time [options] command [arguments...]

DESCRIPTION
       The  time  command runs the specified program command with
       the given arguments.  When command finishes, time writes a
       message  to standard output giving timing statistics about
       this program run.  These statistics  consist  of  (i)  the
       elapsed real time between invocation and termination, (ii)
       the user CPU time (the sum of the tms_utime and tms_cutime
       values in a struct tms as returned by times(2)), and (iii)
       the  system  CPU  time  (the  sum  of  the  tms_stime  and
       tms_cstime   values   in  a  struct  tms  as  returned  by
       times(2)).
...

Et si on l'essaye sur notre programme voici ce que l'on obtient :

Ready time ./mandelbrot
43.59user 0.08system 0:43.95elapsed 99%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (78major+781minor)pagefaults 0swaps
Ready 

Et ici on a le détail des ressources consommées. C'est un peu le fouilli, mais en gros on voit que le programme à consommer 43,59 secondes de CPU en user et 0,08 seconde de CPU en system, il s'est écoulé 43,95 secondes entre le début et la fin du programme, ce qui fait que le programme à consommer 99% du CPU pendant cette période.

L'interêt du programme time c'est qu'il donne les ressources réellement consommées ce qui est plus fiable que le délai qui s'est écoulé entre le début et la fin du programme. En effet la plupart des machines sont multitaches, et on ne se rend plus forcément compte que l'on a plusieurs programmes qui tournent et qui font varier la durée totale d'éxécution. Ainsi par exemple j'ai relancer la même commande mais en veillant à faire tourner un autre programme simultannemment.

Ready time ./mandelbrot
44.81user 0.14system 1:14.62elapsed 60%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (78major+781minor)pagefaults 0swaps
Ready 

On constate que la consommation CPU est un peu près la même, mais que le temps total d'execution est bien plus long.

Une expérience un peu plus sérieuse

Protocol

Passons à des choses un peu plus sérieuse. Comme on l'a dit, on va utiliser la commande time pour mesurer la performance d'un programme. Pour être plus précis, on va utiliser la somme du temps user et du temps system.

Ainsi pour nos deux précédents, on dirait que le programme a mis respectivement 43,67 secondes et 44,95 secondes. Il est vrai qu'il un peu pénible de ne pas toujours avoir le même temps, mais les spécialistes des microprocesseurs vous expliqueront que sur les machines actuelles avec toutes les techniques de caches et de pipelines, c'est très dure de reproduire deux fois exactement le même phénomène.

Maintenant rentrons dans le coeur du sujet, c'est à dire les options de compilation.

Notre programme test a été compilé pour notre premier test de la manière suivante :

Ready  cc mandelbrot.c -o mandelbrot

Comme tout bon développeur sait, le compilateur a une multitude d'option de compilation. Ces options dépendant énormement des compilateurs utilisés, on va supposer que l'on utilise le compilateur gcc (pour être plus précis gcc 3.0.1).

Dans un premier temps on va se contenter d'étudier l'effet de l'option -Ox ou x indique le niveau d'optimisation souhaiter. Dans un premier temps, le reflexe consiste bien sur a regarder ce que dit le man :

Ready  man gcc

...

       These options control various sorts of optimizations:

       -O
       -O1 Optimize.  Optimizing compilation takes somewhat more
           time, and a lot more memory for a large function.

           Without -O, the compiler's goal is to reduce the cost
           of compilation and to make debugging produce the
           expected results.  Statements are independent: if you
           stop the program with a breakpoint between statements,
           you can then assign a new value to any variable or
           change the program counter to any other statement in
           the function and get exactly the results you would
           expect from the source code.

           Without -O, the compiler only allocates variables
           declared "register" in registers.  The resulting com­
           piled code is a little worse than produced by PCC
           without -O.

           With -O, the compiler tries to reduce code size and
           execution time.

           When you specify -O, the compiler turns on -fthread-
           jumps and -fdefer-pop on all machines.  The compiler
           turns on -fdelayed-branch on machines that have delay
           slots, and -fomit-frame-pointer on machines that can
           support debugging even without a frame pointer.  On
           some machines the compiler also turns on other flags.

       -O2 Optimize even more.  GCC performs nearly all supported
           optimizations that do not involve a space-speed trade­
           off.  The compiler does not perform loop unrolling or
           function inlining when you specify -O2.  As compared
           to -O, this option increases both compilation time and
           the performance of the generated code.

           -O2 turns on all optional optimizations except for
           loop unrolling, function inlining, and register renam­
           ing.  It also turns on the -fforce-mem option on all
           machines and frame pointer elimination on machines
           where doing so does not interfere with debugging.

       -O3 Optimize yet more.  -O3 turns on all optimizations
           specified by -O2 and also turns on the -finline-func­
           tions and -frename-registers options.

       -O0 Do not optimize.

       -Os Optimize for size.  -Os enables all -O2 optimizations
           that do not typically increase code size.  It also
           performs further optimizations designed to reduce code
           size.
...

On retiendra donc les optimisations -O0, -01, -02, -03 et -0s. Comme beaucoup de bidouilleur on constaté que gcc ne refuse pas les options d'optimisation plus dure (-04, -05 et plus), nous allons les inclures pour mieux voir que cela n'apporte rien de plus à -03. (remarque ajoutée après : hormis un contexte très précis, ceci n'apporte rien)

Une dernière chose avant de passer à l'expérience en elle-même. Ces types de benchmarck dépendent beaucoup des caractéristiques de la machine, donc voici les caractéristiques de ma machine :

Ready cat /proc/cpuinfo
processor	: 0
vendor_id	: AuthenticAMD
cpu family	: 6
model		: 4
model name	: AMD Athlon(tm) Processor
stepping	: 2
cpu MHz		: 849.625
cache size	: 256 KB
fdiv_bug	: no
hlt_bug		: no
f00f_bug	: no
coma_bug	: no
fpu		: yes
fpu_exception	: yes
cpuid level	: 1
wp		: yes
flags		: fpu vme de pse tsc msr pae mce cx8 sep mtrr pge mca cmov pat pse36 mmx fxsr syscall mmxext 3dnowext 3dnow
bogomips	: 1690.82

Ready 

Expérience

Il ne nous reste plus qu'à travailler et à essayer toutes les combinaisons :

Ready gcc -O0 mandelbrot.c -o mandelbrot
Ready time ./mandelbrot
43.84user 0.10system 0:46.24elapsed 95%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (78major+781minor)pagefaults 0swaps
Ready gcc -O1 mandelbrot.c -o mandelbrot
Ready time ./mandelbrot
24.13user 0.05system 0:25.39elapsed 95%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (78major+781minor)pagefaults 0swaps
Ready gcc -O2 mandelbrot.c -o mandelbrot
Ready time ./mandelbrot
22.38user 0.04system 0:23.52elapsed 95%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (78major+781minor)pagefaults 0swaps
Ready gcc -O3 mandelbrot.c -o mandelbrot
Ready time ./mandelbrot
22.59user 0.04system 0:23.97elapsed 94%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (78major+781minor)pagefaults 0swaps
Ready gcc -O4 mandelbrot.c -o mandelbrot
Ready time ./mandelbrot
22.59user 0.06system 0:24.25elapsed 93%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (78major+781minor)pagefaults 0swaps
Ready gcc -O5 mandelbrot.c -o mandelbrot
Ready time ./mandelbrot
22.60user 0.05system 0:24.88elapsed 93%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (78major+781minor)pagefaults 0swaps
Ready gcc -Os mandelbrot.c -o mandelbrot
Ready time ./mandelbrot
21.81user 0.07system 0:22.98elapsed 95%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (78major+781minor)pagefaults 0swaps
Ready 

Je vous l'accorde comme cela, c'est pas pas très lisible. Si je vous ai tout mis c'est surtout dans un but pédagogique. Allez, je remet tout dans un tableau :

optiontemps en seconde
-0043,94
-0124,18
-0222,42
-0322,63
-0422,65
-0522,65
-0s21,88

Interprétation des résultats

J'ai rapidement trois remarques à faire :

  1. les temps diffèrent légèrement pour les options -O3, -O4, -O5 alors que j'avais annoncé que c'était la même chose.
  2. l'option -O2 optient de meilleurs résultats que -O3.
  3. la grande gagnante c'est l'option -Os.

Pour la première remarque, je vous l'ai déjà expliqué, on a beaucoup de mal à reproduire deux fois la même chose sur la machine moderne.

Alors pour mieux vous convaincre, que -O3, -O4, -05, je vais utiliser la commande cmp.

Ready man cmp

CMP(1)            Manuel de l'utilisateur Linux            CMP(1)

NOM
       cmp - Comparer deux fichiers.

SYNOPSIS
       cmp [-l|-s] fichier1 fichier2 [décal1[décal2]]

DESCRIPTION
       L'utilitaire  cmp  compare  deux fichiers de tous types et
       écrit le résultat sur la sortie standard.  Par défaut, cmp
       est  silencieux  si  les  fichiers  sont identiques; s'ils
       diffèrent, les numéros d'octet et de ligne de la  première
       différence détectée sont affichés.

...

Et je vais vous montrer que les binaires sont les mêmes :

Ready ll
total 16
-rw-------    1 manu     users         938 oct 23 22:29 makefile
-rw-------    1 manu     users          75 oct 23 22:08 makefile~
-rw-------    1 manu     users        1394 oct 23 23:01 mandelbrot.c
-rw-------    1 manu     users         441 oct 23 22:06 mandelbrot.c~
Ready gcc -O3 mandelbrot.c -o mandelbrot_O3
Ready gcc -O4 mandelbrot.c -o mandelbrot_O4
Ready gcc -O5 mandelbrot.c -o mandelbrot_O5
Ready ll
total 64
-rw-------    1 manu     users         938 oct 23 22:29 makefile
-rw-------    1 manu     users          75 oct 23 22:08 makefile~
-rw-------    1 manu     users        1394 oct 23 23:01 mandelbrot.c
-rw-------    1 manu     users         441 oct 23 22:06 mandelbrot.c~
-rwx------    1 manu     users       14181 oct 24 22:08 mandelbrot_O3*
-rwx------    1 manu     users       14181 oct 24 22:08 mandelbrot_O4*
-rwx------    1 manu     users       14181 oct 24 22:08 mandelbrot_O5*
Ready cmp mandelbrot_O3 mandelbrot_O4
Ready cmp mandelbrot_O3 mandelbrot_O5
Ready 

Ready ll
total 8
-rw-------    1 manu     users         938 oct 23 22:29 makefile
-rw-------    1 manu     users        1630 oct 25 20:19 mandelbrot.c
Ready gcc -O3 mandelbrot.c -o mandelbrot_O3
Ready gcc -O4 mandelbrot.c -o mandelbrot_O4
Ready gcc -O5 mandelbrot.c -o mandelbrot_O5
Ready ll
total 56
-rw-------    1 manu     users         938 oct 23 22:29 makefile
-rw-------    1 manu     users        1630 oct 25 20:19 mandelbrot.c
-rwx------    1 manu     users       14345 oct 25 20:48 mandelbrot_O3*
-rwx------    1 manu     users       14345 oct 25 20:48 mandelbrot_O4*
-rwx------    1 manu     users       14345 oct 25 20:49 mandelbrot_O5*
Ready cmp mandelbrot_O3 mandelbrot_O4
Ready cmp mandelbrot_O3 mandelbrot_O5
Ready 

Bon c'est claire, on oublie maintenant les options -O4 et -O5. (remarque ajouter après : je ne me suis pas mis dans le contexte ou ces options apportent quelques choses.)

L'autre qui m'intrigue plus, c'est que le meilleur résultat est obtenu avec -Os. En gros cela voudrait dire qu'en optimisant la taille du code, il tient entierement dans les différents caches et le processeur arrive à travailler plus vite.

Nouvelles explorations

Je ne sait pas comment vérifier cela sérieusement, mais en tout cas je vais jetter un coup d'oeil au code générer. En effet si on s'appuye sur le man de gcc, on apprend que l'on peut obtenir le code assembleur générer :

Ready man gcc

...

       -S  Stop after the stage of compilation proper; do not
           assemble.  The output is in the form of an assembler
           code file for each non-assembler input file specified.

...

Et si on l'assaye sur notre programme :

Ready ll
total 56
-rw-------    1 manu     users         938 oct 23 22:29 makefile
-rw-------    1 manu     users        1630 oct 25 20:19 mandelbrot.c
Ready gcc -O0 -S mandelbrot.c -o mandelbrot_O0.s
Ready gcc -O0 -S mandelbrot.c -o mandelbrot_O0.s
Ready gcc -O1 -S mandelbrot.c -o mandelbrot_O1.s
Ready gcc -O2 -S mandelbrot.c -o mandelbrot_O2.s
Ready gcc -O3 -S mandelbrot.c -o mandelbrot_O3.s
Ready gcc -Os -S mandelbrot.c -o mandelbrot_Os.s
Ready ll
total 32
-rw-------    1 manu     users         938 oct 23 22:29 makefile
-rw-------    1 manu     users        1630 oct 25 20:19 mandelbrot.c
-rw-------    1 manu     users        3338 oct 25 20:51 mandelbrot_O0.s
-rw-------    1 manu     users        2669 oct 25 20:51 mandelbrot_O1.s
-rw-------    1 manu     users        3063 oct 25 20:51 mandelbrot_O2.s
-rw-------    1 manu     users        4810 oct 25 20:51 mandelbrot_O3.s
-rw-------    1 manu     users        2535 oct 25 20:51 mandelbrot_Os.s
Ready 

et si on met le tout en forme :

mandelbrot_O0.s mandelbrot_O1.s mandelbrot_O2.s mandelbrot_O3.s mandelbrot_Os.s
	.file	"mandelbrot.c"
	.section	.rodata
	.align 8
.LC0:
	.long	0x0,0x40100000
	.text
	.align 16
.globl mandelpoint
	.type	mandelpoint,@function
mandelpoint:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$56, %esp
	movl	8(%ebp), %eax
	movl	12(%ebp), %edx
	movl	%eax, -8(%ebp)
	movl	%edx, -4(%ebp)
	movl	16(%ebp), %eax
	movl	20(%ebp), %edx
	movl	%eax, -16(%ebp)
	movl	%edx, -12(%ebp)
	movl	$0, -20(%ebp)
	movl	-8(%ebp), %eax
	movl	-4(%ebp), %edx
	movl	%eax, -32(%ebp)
	movl	%edx, -28(%ebp)
	movl	-16(%ebp), %eax
	movl	-12(%ebp), %edx
	movl	%eax, -40(%ebp)
	movl	%edx, -36(%ebp)
	fldl	-32(%ebp)
	fmull	-32(%ebp)
	fstpl	-48(%ebp)
	fldl	-40(%ebp)
	fmull	-40(%ebp)
	fstpl	-56(%ebp)
	.p2align 4
.L2:
	movl	-20(%ebp), %eax
	cmpl	24(%ebp), %eax
	jge	.L3
	fldl	-48(%ebp)
	faddl	-56(%ebp)
	fldl	.LC0
	fucompp
	fnstsw	%ax
	sahf
	ja	.L4
	jmp	.L3
	.p2align 4,,7
.L4:
	fldl	-32(%ebp)
	fadd	%st(0), %st
	fmull	-40(%ebp)
	faddl	-16(%ebp)
	fstpl	-40(%ebp)
	fldl	-48(%ebp)
	fsubl	-56(%ebp)
	faddl	-8(%ebp)
	fstpl	-32(%ebp)
	fldl	-32(%ebp)
	fmull	-32(%ebp)
	fstpl	-48(%ebp)
	fldl	-40(%ebp)
	fmull	-40(%ebp)
	fstpl	-56(%ebp)
	leal	-20(%ebp), %eax
	incl	(%eax)
	jmp	.L2
	.p2align 4,,7
.L3:
	movl	-20(%ebp), %eax
	movl	%ebp, %esp
	popl	%ebp
	ret
.Lfe1:
	.size	mandelpoint,.Lfe1-mandelpoint
	.align 16
.globl mandelbrot
	.type	mandelbrot,@function
mandelbrot:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$56, %esp
	movl	8(%ebp), %eax
	movl	12(%ebp), %edx
	movl	%eax, -8(%ebp)
	movl	%edx, -4(%ebp)
	movl	16(%ebp), %eax
	movl	20(%ebp), %edx
	movl	%eax, -16(%ebp)
	movl	%edx, -12(%ebp)
	movl	24(%ebp), %eax
	movl	28(%ebp), %edx
	movl	%eax, -24(%ebp)
	movl	%edx, -20(%ebp)
	movl	32(%ebp), %eax
	movl	36(%ebp), %edx
	movl	%eax, -32(%ebp)
	movl	%edx, -28(%ebp)
	movl	$0, -36(%ebp)
	.p2align 4
.L7:
	movl	-36(%ebp), %eax
	cmpl	40(%ebp), %eax
	jl	.L10
	jmp	.L8
	.p2align 4,,7
.L10:
	movl	$0, -40(%ebp)
	.p2align 4
.L11:
	movl	-40(%ebp), %eax
	cmpl	44(%ebp), %eax
	jl	.L14
	leal	-36(%ebp), %eax
	incl	(%eax)
	jmp	.L7
	.p2align 4,,7
.L14:
	fldl	-16(%ebp)
	fsubl	-8(%ebp)
	fildl	-36(%ebp)
	fmulp	%st, %st(1)
	fildl	40(%ebp)
	fdivrp	%st, %st(1)
	fldl	-8(%ebp)
	faddp	%st, %st(1)
	fstpl	-48(%ebp)
	fldl	-32(%ebp)
	fsubl	-24(%ebp)
	fildl	-40(%ebp)
	fmulp	%st, %st(1)
	fildl	44(%ebp)
	fdivrp	%st, %st(1)
	fldl	-24(%ebp)
	faddp	%st, %st(1)
	fstpl	-56(%ebp)
	subl	$12, %esp
	pushl	48(%ebp)
	pushl	-52(%ebp)
	pushl	-56(%ebp)
	pushl	-44(%ebp)
	pushl	-48(%ebp)
	call	mandelpoint
	addl	$32, %esp
	movl	%eax, %ecx
	movl	-40(%ebp), %eax
	imull	40(%ebp), %eax
	addl	-36(%ebp), %eax
	leal	0(,%eax,4), %edx
	movl	52(%ebp), %eax
	movl	%ecx, (%eax,%edx)
	leal	-40(%ebp), %eax
	incl	(%eax)
	jmp	.L11
	.p2align 4,,7
.L8:
	movl	%ebp, %esp
	popl	%ebp
	ret
.Lfe2:
	.size	mandelbrot,.Lfe2-mandelbrot
	.align 16
.globl main
	.type	main,@function
main:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$3145768, %esp
	andl	$-16, %esp
	movl	$0, -12(%ebp)
	.p2align 4
.L16:
	cmpl	$9, -12(%ebp)
	jle	.L19
	jmp	.L17
	.p2align 4,,7
.L19:
	leal	-3145752(%ebp), %eax
	pushl	%eax
	pushl	$1024
	pushl	$768
	pushl	$1024
	pushl	$1073217536
	pushl	$0
	pushl	$-1074266112
	pushl	$0
	pushl	$1073217536
	pushl	$0
	pushl	$-1073479680
	pushl	$0
	call	mandelbrot
	addl	$48, %esp
	leal	-12(%ebp), %eax
	incl	(%eax)
	jmp	.L16
	.p2align 4,,7
.L17:
	movl	$0, %eax
	movl	%ebp, %esp
	popl	%ebp
	ret
.Lfe3:
	.size	main,.Lfe3-main
	.ident	"GCC: (GNU) 3.0.1"

	.file	"mandelbrot.c"
	.section	.rodata
	.align 8
.LC0:
	.long	0x0,0x40100000
	.text
	.align 16
.globl mandelpoint
	.type	mandelpoint,@function
mandelpoint:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$8, %esp
	fldl	8(%ebp)
	fldl	16(%ebp)
	movl	24(%ebp), %edx
	movl	$0, %ecx
	fld	%st(1)
	fld	%st(1)
	fld	%st(1)
	fmul	%st(2), %st
	fld	%st(1)
	fmul	%st(2), %st
	cmpl	%edx, %ecx
	jge	.L9
	fld	%st(1)
	fadd	%st(1), %st
	fldl	.LC0
	fstl	-8(%ebp)
	fucompp
	fnstsw	%ax
	sahf
	jbe	.L8
	jmp	.L4
.L10:
	fxch	%st(2)
	fxch	%st(3)
	fxch	%st(2)
	.p2align 4
.L4:
	fld	%st(3)
	faddp	%st, %st(4)
	fxch	%st(3)
	fmulp	%st, %st(2)
	fxch	%st(1)
	fadd	%st(3), %st
	fxch	%st(1)
	fsubp	%st, %st(2)
	fxch	%st(1)
	fadd	%st(3), %st
	fld	%st(0)
	fmul	%st(1), %st
	fld	%st(2)
	fmul	%st(3), %st
	incl	%ecx
	cmpl	%edx, %ecx
	jge	.L9
	fld	%st(1)
	fadd	%st(1), %st
	fldl	-8(%ebp)
	fucompp
	fnstsw	%ax
	sahf
	ja	.L10
.L8:
.L9:
	fstp	%st(0)
	fstp	%st(0)
	fstp	%st(0)
	fstp	%st(0)
	fstp	%st(0)
	fstp	%st(0)
	movl	%ecx, %eax
	movl	%ebp, %esp
	popl	%ebp
	ret
.Lfe1:
	.size	mandelpoint,.Lfe1-mandelpoint
	.align 16
.globl mandelbrot
	.type	mandelbrot,@function
mandelbrot:
	pushl	%ebp
	movl	%esp, %ebp
	pushl	%edi
	pushl	%esi
	pushl	%ebx
	subl	$28, %esp
	movl	$0, -20(%ebp)
	jmp	.L22
	.p2align 4,,7
.L15:
	movl	$0, %ebx
	cmpl	44(%ebp), %ebx
	jge	.L14
	fldl	16(%ebp)
	fsubl	8(%ebp)
	fildl	-20(%ebp)
	fmulp	%st, %st(1)
	fildl	40(%ebp)
	fdivrp	%st, %st(1)
	faddl	8(%ebp)
	fstpl	-32(%ebp)
	movl	-32(%ebp), %esi
	movl	-28(%ebp), %edi
	.p2align 4
.L19:
	fldl	32(%ebp)
	fsubl	24(%ebp)
	pushl	%ebx
	fildl	(%esp)
	leal	-8(%esp), %esp
	fmulp	%st, %st(1)
	fildl	44(%ebp)
	fdivrp	%st, %st(1)
	faddl	24(%ebp)
	pushl	48(%ebp)
	leal	-8(%esp), %esp
	fstpl	(%esp)
	pushl	%edi
	pushl	%esi
	call	mandelpoint
	movl	40(%ebp), %edx
	imull	%ebx, %edx
	addl	-20(%ebp), %edx
	movl	52(%ebp), %ecx
	movl	%eax, (%ecx,%edx,4)
	addl	$32, %esp
	incl	%ebx
	cmpl	44(%ebp), %ebx
	jl	.L19
.L14:
	incl	-20(%ebp)
.L22:
	movl	40(%ebp), %eax
	cmpl	%eax, -20(%ebp)
	jl	.L15
	leal	-12(%ebp), %esp
	popl	%ebx
	popl	%esi
	popl	%edi
	popl	%ebp
	ret
.Lfe2:
	.size	mandelbrot,.Lfe2-mandelbrot
	.align 16
.globl main
	.type	main,@function
main:
	pushl	%ebp
	movl	%esp, %ebp
	pushl	%esi
	pushl	%ebx
	subl	$3145728, %esp
	andl	$-16, %esp
	movl	$0, %ebx
	leal	-3145736(%ebp), %esi
	.p2align 4
.L27:
	pushl	%esi
	pushl	$1024
	pushl	$768
	pushl	$1024
	pushl	$1073217536
	pushl	$0
	pushl	$-1074266112
	pushl	$0
	pushl	$1073217536
	pushl	$0
	pushl	$-1073479680
	pushl	$0
	call	mandelbrot
	addl	$48, %esp
	incl	%ebx
	cmpl	$9, %ebx
	jle	.L27
	movl	$0, %eax
	leal	-8(%ebp), %esp
	popl	%ebx
	popl	%esi
	popl	%ebp
	ret
.Lfe3:
	.size	main,.Lfe3-main
	.ident	"GCC: (GNU) 3.0.1"
	.file	"mandelbrot.c"
	.section	.rodata
	.align 8
.LC0:
	.long	0x0,0x40100000
	.text
	.align 16
.globl mandelpoint
	.type	mandelpoint,@function
mandelpoint:
	pushl	%ebp
	movl	%esp, %ebp
	movl	24(%ebp), %edx
	fldl	8(%ebp)
	xorl	%ecx, %ecx
	fldl	16(%ebp)
	cmpl	%edx, %ecx
	fld	%st(1)
	fld	%st(1)
	fld	%st(1)
	fld	%st(1)
	fxch	%st(1)
	fmul	%st(0), %st
	fxch	%st(1)
	fmul	%st(0), %st
	jge	.L10
	fldl	.LC0
	jmp	.L7
	.p2align 4,,7
.L4:
	fxch	%st(4)
	fadd	%st(0), %st
	incl	%ecx
	cmpl	%edx, %ecx
	fmulp	%st, %st(3)
	fsubrp	%st, %st(1)
	fxch	%st(1)
	fadd	%st(3), %st
	fxch	%st(1)
	fadd	%st(4), %st
	fld	%st(1)
	fld	%st(1)
	fmul	%st(0), %st
	fxch	%st(1)
	fmul	%st(0), %st
	jge	.L9
	fxch	%st(1)
	fxch	%st(2)
	fxch	%st(4)
.L7:
	fld	%st(2)
	fadd	%st(2), %st
	fxch	%st(1)
	fucom	%st(1)
	fnstsw	%ax
	fstp	%st(1)
	sahf
	ja	.L4
.L9:
	fstp	%st(0)
.L10:
	fstp	%st(0)
	fstp	%st(0)
	fstp	%st(0)
	fstp	%st(0)
	fstp	%st(0)
	fstp	%st(0)
	popl	%ebp
	movl	%ecx, %eax
	ret
.Lfe1:
	.size	mandelpoint,.Lfe1-mandelpoint
	.align 16
.globl mandelbrot
	.type	mandelbrot,@function
mandelbrot:
	pushl	%ebp
	movl	%esp, %ebp
	pushl	%edi
	xorl	%edi, %edi
	pushl	%esi
	pushl	%ebx
	subl	$92, %esp
	cmpl	40(%ebp), %edi
	fldl	8(%ebp)
	fldl	24(%ebp)
	jge	.L24
	.p2align 4
.L15:
	xorl	%esi, %esi
	cmpl	44(%ebp), %esi
	jge	.L23
	pushl	%edi
	movl	52(%ebp), %eax
	fildl	(%esp)
	addl	$4, %esp
	leal	(%eax,%edi,4), %ebx
	fldl	16(%ebp)
	fildl	40(%ebp)
	fldl	32(%ebp)
	fxch	%st(2)
	fsub	%st(5), %st
	fildl	44(%ebp)
	fxch	%st(3)
	fsub	%st(5), %st
	fxch	%st(1)
	fmulp	%st, %st(4)
	fxch	%st(3)
	fdivp	%st, %st(1)
	fadd	%st(4), %st
	jmp	.L19
.L25:
	fxch	%st(4)
	fxch	%st(1)
	fxch	%st(3)
	fxch	%st(2)
	fxch	%st(1)
	.p2align 4
.L19:
	pushl	%esi
	movl	48(%ebp), %eax
	incl	%esi
	fildl	(%esp)
	fxch	%st(1)
	subl	$8, %esp
	pushl	%eax
	subl	$16, %esp
	fstl	(%esp)
	fstpt	-40(%ebp)
	fxch	%st(2)
	fld	%st(0)
	fstpt	-56(%ebp)
	fxch	%st(1)
	fld	%st(0)
	fstpt	-72(%ebp)
	fxch	%st(2)
	fmulp	%st, %st(1)
	fxch	%st(2)
	fld	%st(0)
	fstpt	-88(%ebp)
	fxch	%st(3)
	fstpt	-104(%ebp)
	fdivrp	%st, %st(1)
	faddp	%st, %st(1)
	fstpl	8(%esp)
	call	mandelpoint
	movl	%eax, (%ebx)
	addl	$32, %esp
	movl	40(%ebp), %eax
	cmpl	44(%ebp), %esi
	fldt	-40(%ebp)
	leal	(%ebx,%eax,4), %ebx
	fldt	-56(%ebp)
	fldt	-72(%ebp)
	fldt	-88(%ebp)
	fldt	-104(%ebp)
	jl	.L25
	fstp	%st(2)
	fstp	%st(2)
	fstp	%st(2)
.L23:
	incl	%edi
	cmpl	40(%ebp), %edi
	jl	.L15
.L24:
	fstp	%st(0)
	fstp	%st(0)
	leal	-12(%ebp), %esp
	popl	%ebx
	popl	%esi
	popl	%edi
	popl	%ebp
	ret
.Lfe2:
	.size	mandelbrot,.Lfe2-mandelbrot
	.align 16
.globl main
	.type	main,@function
main:
	pushl	%ebp
	movl	%esp, %ebp
	pushl	%esi
	leal	-3145736(%ebp), %esi
	pushl	%ebx
	movl	$9, %ebx
	subl	$3145728, %esp
	andl	$-16, %esp
	.p2align 4
.L30:
	pushl	%esi
	pushl	$1024
	pushl	$768
	pushl	$1024
	pushl	$1073217536
	pushl	$0
	pushl	$-1074266112
	pushl	$0
	pushl	$1073217536
	pushl	$0
	pushl	$-1073479680
	pushl	$0
	call	mandelbrot
	addl	$48, %esp
	decl	%ebx
	jns	.L30
	leal	-8(%ebp), %esp
	xorl	%eax, %eax
	popl	%ebx
	popl	%esi
	popl	%ebp
	ret
.Lfe3:
	.size	main,.Lfe3-main
	.ident	"GCC: (GNU) 3.0.1"

	.file	"mandelbrot.c"
	.section	.rodata
	.align 8
.LC2:
	.long	0x0,0xc0040000
	.align 8
.LC4:
	.long	0x0,0xbff80000
	.align 8
.LC5:
	.long	0x0,0x40100000
	.align 8
.LC6:
	.long	0x0,0x40900000
	.align 8
.LC7:
	.long	0x0,0x40880000
	.align 8
.LC8:
	.long	0x0,0x40080000
	.text
	.align 16
.globl main
	.type	main,@function
main:
	pushl	%ebp
	xorl	%edx, %edx
	movl	%esp, %ebp
	pushl	%edi
	movl	$1074790400, %ecx
	leal	-3145752(%ebp), %edi
	pushl	%esi
	xorl	%esi, %esi
	pushl	%ebx
	subl	$3145756, %esp
	movl	%ecx, -3145756(%ebp)
	andl	$-16, %esp
	movl	%edx, -3145760(%ebp)
	fldl	-3145760(%ebp)
	.p2align 4
.L28:
	xorl	%ebx, %ebx
	.p2align 4
.L31:
	pushl	%ebx
	xorl	%ecx, %ecx
	leal	(%edi,%ebx,4), %edx
	fildl	(%esp)
	addl	$4, %esp
	fmull	.LC5
	fdivl	.LC6
	faddl	.LC2
	.p2align 4
.L34:
	pushl	%ecx
	fld	%st(0)
	fld	%st(0)
	fildl	(%esp)
	fxch	%st(1)
	xorl	%eax, %eax
	fmul	%st(0), %st
	movl	%eax, -3145764(%ebp)
	addl	$4, %esp
	fld	%st(0)
	fxch	%st(2)
	fmull	.LC8
	fdivl	.LC7
	faddl	.LC4
	fld	%st(0)
	fld	%st(0)
	fmul	%st(0), %st
	jmp	.L50
	.p2align 4,,7
.L37:
	fxch	%st(4)
	incl	-3145764(%ebp)
	fadd	%st(0), %st
	cmpl	$1024, -3145764(%ebp)
	fmulp	%st, %st(4)
	fxch	%st(1)
	fsubp	%st, %st(5)
	fadd	%st, %st(2)
	fxch	%st(4)
	fadd	%st(3), %st
	fld	%st(2)
	fld	%st(1)
	fmul	%st(0), %st
	fxch	%st(1)
	fmul	%st(0), %st
	jge	.L51
	fld	%st(1)
	fxch	%st(4)
	fxch	%st(7)
	fxch	%st(2)
	fxch	%st(3)
	fxch	%st(5)
	fxch	%st(1)
.L50:
	fadd	%st, %st(4)
	fxch	%st(7)
	fucom	%st(4)
	fnstsw	%ax
	fstp	%st(4)
	sahf
	ja	.L37
.L51:
	fstp	%st(0)
	fstp	%st(0)
	fstp	%st(0)
	fstp	%st(1)
	fstp	%st(2)
	movl	-3145764(%ebp), %eax
	incl	%ecx
	movl	%eax, (%edx)
	addl	$4096, %edx
	cmpl	$768, %ecx
	jl	.L34
	fstp	%st(0)
	incl	%ebx
	cmpl	$1024, %ebx
	jl	.L31
	incl	%esi
	cmpl	$9, %esi
	jle	.L28
	fstp	%st(0)
	leal	-12(%ebp), %esp
	xorl	%eax, %eax
	popl	%ebx
	popl	%esi
	popl	%edi
	popl	%ebp
	ret
.Lfe1:
	.size	main,.Lfe1-main
	.section	.rodata
	.align 8
.LC0:
	.long	0x0,0x40100000
	.text
	.align 16
.globl mandelpoint
	.type	mandelpoint,@function
mandelpoint:
	pushl	%ebp
	movl	%esp, %ebp
	movl	24(%ebp), %edx
	fldl	8(%ebp)
	xorl	%ecx, %ecx
	fldl	16(%ebp)
	cmpl	%edx, %ecx
	fld	%st(1)
	fld	%st(1)
	fld	%st(1)
	fld	%st(1)
	fxch	%st(1)
	fmul	%st(0), %st
	fxch	%st(1)
	fmul	%st(0), %st
	jge	.L55
	fldl	.LC0
	jmp	.L52
	.p2align 4,,7
.L4:
	fxch	%st(4)
	fadd	%st(0), %st
	incl	%ecx
	cmpl	%edx, %ecx
	fmulp	%st, %st(3)
	fsubrp	%st, %st(1)
	fxch	%st(1)
	fadd	%st(3), %st
	fxch	%st(1)
	fadd	%st(4), %st
	fld	%st(1)
	fld	%st(1)
	fmul	%st(0), %st
	fxch	%st(1)
	fmul	%st(0), %st
	jge	.L54
	fxch	%st(1)
	fxch	%st(2)
	fxch	%st(4)
.L52:
	fld	%st(2)
	fadd	%st(2), %st
	fxch	%st(1)
	fucom	%st(1)
	fnstsw	%ax
	fstp	%st(1)
	sahf
	ja	.L4
.L54:
	fstp	%st(0)
.L55:
	fstp	%st(0)
	fstp	%st(0)
	fstp	%st(0)
	fstp	%st(0)
	fstp	%st(0)
	fstp	%st(0)
	popl	%ebp
	movl	%ecx, %eax
	ret
.Lfe2:
	.size	mandelpoint,.Lfe2-mandelpoint
	.align 16
.globl mandelbrot
	.type	mandelbrot,@function
mandelbrot:
	pushl	%ebp
	movl	%esp, %ebp
	pushl	%edi
	pushl	%esi
	pushl	%ebx
	xorl	%ebx, %ebx
	subl	$36, %esp
	cmpl	40(%ebp), %ebx
	jge	.L56
	.p2align 4
.L11:
	xorl	%ecx, %ecx
	cmpl	44(%ebp), %ecx
	jge	.L57
	pushl	%ebx
	movl	52(%ebp), %eax
	fildl	(%esp)
	addl	$4, %esp
	leal	(%eax,%ebx,4), %edx
	fldl	16(%ebp)
	fildl	40(%ebp)
	fxch	%st(1)
	movl	40(%ebp), %eax
	fsubl	8(%ebp)
	fildl	44(%ebp)
	sall	$2, %eax
	fldl	32(%ebp)
	fxch	%st(2)
	fmulp	%st, %st(4)
	fxch	%st(1)
	movl	%eax, -48(%ebp)
	fsubl	24(%ebp)
	fxch	%st(3)
	fdivp	%st, %st(2)
	fxch	%st(1)
	faddl	8(%ebp)
	fxch	%st(1)
	fstpl	-32(%ebp)
	fxch	%st(1)
	fstpl	-24(%ebp)
	.p2align 4
.L15:
	pushl	%ecx
	movl	48(%ebp), %eax
	fld	%st(0)
	fildl	(%esp)
	movl	$0, -44(%ebp)
	addl	$4, %esp
	fld	%st(1)
	cmpl	%eax, -44(%ebp)
	fmul	%st(0), %st
	fxch	%st(1)
	fmull	-24(%ebp)
	fdivl	-32(%ebp)
	faddl	24(%ebp)
	fld	%st(0)
	fld	%st(0)
	fmul	%st(0), %st
	jge	.L61
	xorl	%edi, %edi
	movl	$1074790400, %eax
	fld	%st(3)
	movl	%eax, -36(%ebp)
	fadd	%st(1), %st
	movl	%edi, -40(%ebp)
	fldl	-40(%ebp)
	jmp	.L58
	.p2align 4,,7
.L18:
	fxch	%st(5)
	incl	-44(%ebp)
	fadd	%st(0), %st
	movl	48(%ebp), %eax
	fmulp	%st, %st(2)
	cmpl	%eax, -44(%ebp)
	fsubrp	%st, %st(3)
	fadd	%st(1), %st
	fxch	%st(2)
	fadd	%st(4), %st
	fld	%st(2)
	fld	%st(1)
	fmul	%st(0), %st
	fxch	%st(1)
	fmul	%st(0), %st
	jge	.L60
	fld	%st(1)
	fadd	%st(1), %st
	fxch	%st(1)
	fxch	%st(2)
	fxch	%st(5)
	fxch	%st(3)
	fxch	%st(6)
.L58:
	fucom	%st(1)
	fnstsw	%ax
	fstp	%st(1)
	sahf
	ja	.L18
.L60:
	fstp	%st(0)
.L61:
	fstp	%st(0)
	fstp	%st(0)
	fstp	%st(0)
	fstp	%st(0)
	fstp	%st(0)
	movl	-44(%ebp), %eax
	incl	%ecx
	movl	%eax, (%edx)
	movl	-48(%ebp), %edi
	addl	%edi, %edx
	cmpl	44(%ebp), %ecx
	jl	.L15
	fstp	%st(0)
.L57:
	incl	%ebx
	cmpl	40(%ebp), %ebx
	jl	.L11
.L56:
	addl	$36, %esp
	popl	%ebx
	popl	%esi
	popl	%edi
	popl	%ebp
	ret
.Lfe3:
	.size	mandelbrot,.Lfe3-mandelbrot
	.ident	"GCC: (GNU) 3.0.1"

	.file	"mandelbrot.c"
	.section	.rodata
	.align 8
.LC0:
	.long	0x0,0x40100000
	.text
	.align 16
.globl mandelpoint
	.type	mandelpoint,@function
mandelpoint:
	pushl	%ebp
	movl	%esp, %ebp
	movl	24(%ebp), %edx
	fldl	8(%ebp)
	xorl	%ecx, %ecx
	fldl	16(%ebp)
	cmpl	%edx, %ecx
	fld	%st(1)
	fld	%st(1)
	fld	%st(1)
	fld	%st(1)
	fxch	%st(1)
	fmul	%st(0), %st
	fxch	%st(1)
	fmul	%st(0), %st
	jge	.L10
	fldl	.LC0
	jmp	.L7
	.p2align 4,,7
.L4:
	fxch	%st(4)
	fadd	%st(0), %st
	incl	%ecx
	cmpl	%edx, %ecx
	fmulp	%st, %st(3)
	fsubrp	%st, %st(1)
	fxch	%st(1)
	fadd	%st(3), %st
	fxch	%st(1)
	fadd	%st(4), %st
	fld	%st(1)
	fld	%st(1)
	fmul	%st(0), %st
	fxch	%st(1)
	fmul	%st(0), %st
	jge	.L9
	fxch	%st(1)
	fxch	%st(2)
	fxch	%st(4)
.L7:
	fld	%st(2)
	fadd	%st(2), %st
	fxch	%st(1)
	fucom	%st(1)
	fnstsw	%ax
	fstp	%st(1)
	sahf
	ja	.L4
.L9:
	fstp	%st(0)
.L10:
	fstp	%st(0)
	fstp	%st(0)
	fstp	%st(0)
	fstp	%st(0)
	fstp	%st(0)
	fstp	%st(0)
	popl	%ebp
	movl	%ecx, %eax
	ret
.Lfe1:
	.size	mandelpoint,.Lfe1-mandelpoint
	.align 16
.globl mandelbrot
	.type	mandelbrot,@function
mandelbrot:
	pushl	%ebp
	movl	%esp, %ebp
	pushl	%edi
	xorl	%edi, %edi
	pushl	%esi
	pushl	%ebx
	subl	$12, %esp
	cmpl	40(%ebp), %edi
	jge	.L22
	.p2align 4
.L15:
	xorl	%esi, %esi
	cmpl	44(%ebp), %esi
	jge	.L23
	movl	52(%ebp), %eax
	leal	(%eax,%edi,4), %ebx
	.p2align 4
.L19:
	pushl	%edi
	fildl	(%esp)
	fldl	16(%ebp)
	movl	%esi, (%esp)
	incl	%esi
	fildl	(%esp)
	fxch	%st(1)
	subl	$8, %esp
	fsubl	8(%ebp)
	pushl	48(%ebp)
	fmulp	%st, %st(2)
	subl	$16, %esp
	fildl	40(%ebp)
	fdivrp	%st, %st(2)
	fldl	32(%ebp)
	fxch	%st(2)
	faddl	8(%ebp)
	fxch	%st(2)
	fsubl	24(%ebp)
	fxch	%st(2)
	fstpl	(%esp)
	fmulp	%st, %st(1)
	fildl	44(%ebp)
	fdivrp	%st, %st(1)
	faddl	24(%ebp)
	fstpl	8(%esp)
	call	mandelpoint
	movl	%eax, (%ebx)
	addl	$32, %esp
	movl	40(%ebp), %eax
	cmpl	44(%ebp), %esi
	leal	(%ebx,%eax,4), %ebx
	jl	.L19
.L23:
	incl	%edi
	cmpl	40(%ebp), %edi
	jl	.L15
.L22:
	leal	-12(%ebp), %esp
	popl	%ebx
	popl	%esi
	popl	%edi
	popl	%ebp
	ret
.Lfe2:
	.size	mandelbrot,.Lfe2-mandelbrot
	.align 16
.globl main
	.type	main,@function
main:
	pushl	%ebp
	movl	%esp, %ebp
	pushl	%ebx
	subl	$3145732, %esp
	andl	$-16, %esp
	movl	$9, %ebx
	.p2align 4
.L28:
	leal	-3145736(%ebp), %eax
	pushl	%eax
	pushl	$1024
	pushl	$768
	pushl	$1024
	pushl	$1073217536
	pushl	$0
	pushl	$-1074266112
	pushl	$0
	pushl	$1073217536
	pushl	$0
	pushl	$-1073479680
	pushl	$0
	call	mandelbrot
	addl	$48, %esp
	decl	%ebx
	jns	.L28
	movl	-4(%ebp), %ebx
	xorl	%eax, %eax
	leave
	ret
.Lfe3:
	.size	main,.Lfe3-main
	.ident	"GCC: (GNU) 3.0.1"

Bon, je préviens tout de suite mes connaissances en assembleurs sont assez limitées, donc soyez indulgeant en cas d'erreur.

Une première remarque sur le code sans optimisation, on constate que les variables sont systématiquement chargées en mémoire, ce qui explique les temps assez long. (Sur certaine architecture avec des caches très performant, on arrive à supprimer cette effet)

L'optimisation O1 utilise un peu mieux les registres, donc moins de travail avec la mémoire, d'ou gain de vitesse.

Arrivé à O2, on voit que le comilateur utilise mieux les instructions assembleurs, d'ou encore un petit gain.

Pour la fonction mandelpoint, le code est le même pour les options O2, O3, Os. Il est claire que le programme passe la majorité du temps dans cette fonction. (un autre jour je vous expliquerai comment le voir avec gprof). La différence se fera donc au niveau de la fonction mandelbrot.

En gros on constate que pour O3, le compilateur a "inliné" la fonction mandelpoint et il a modifié l'ordre des fonctions, alors que pour Os, il a simplement mis un code plus petit.

Je n'ai pas d'explication sur pourquoi "inliné" la fonction fait perdre du temps.

Par contre sur pourquoi Os sort gagnant, je pense que l'explication tient du faite que tout le programme tient dans un cache ce qui accèlère énormement l'execution.

Bergeron Etienne m'a confirmé que cette différence de vitesse vient bien du faite que le programme plus petit tient entièrement dans le cache donc s'execute plus rapidement.

C'est tout pour ce soir, suite au prochain numéro !

retour


Emmanuel DUMAS, emmanuel point dumas arobase free point france
Last modified: Thu May 23 11:40:10 CEST 2002