Bonjour à tous et à toutes
Au niveau d'optimisation quelle est la différence entre : While(1){} et for(;; ){}?
Merci d'avance
Bonjour à tous et à toutes
Au niveau d'optimisation quelle est la différence entre : While(1){} et for(;; ){}?
Merci d'avance
Aucune.Ou tellement rien.
Deux fonctions :
Code boucles.c : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 void withFor(void) { for(;;) ; } void withWhile(void) { while(1) ; }
L'assembleur derrière, généré par MinGW:
Il y a deux NOP en plus (qui m'étonnent un peu d'ailleurs). N'importe quelle action à l'intérieur de la boucle coûtera plus que 2 NOP en toute logique.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 PS D:\Users\pgradot\Documents\C\out\Debug> objdump.exe -d .\boucles.o .\boucles.o: file format pe-i386 Disassembly of section .text: 00000000 <_withFor>: 0: 55 push %ebp 1: 89 e5 mov %esp,%ebp 3: eb fe jmp 3 <_withFor+0x3> 00000005 <_withWhile>: 5: 55 push %ebp 6: 89 e5 mov %esp,%ebp 8: eb fe jmp 8 <_withWhile+0x3> a: 90 nop b: 90 nop PS D:\Users\pgradot\Documents\C\out\Debug>
EDIT : en inversant les deux fonctions dans le fichier, les NOP se retrouvent dans withFor(). Les deux fonctions sont donc identiques. Faudrait voir si les NOP ne sont pas un artefact d'objdump ou du fait que ce soit la dernière fonction du fichier.
EDIT bis : ces NOP n'ont vraiment rien à faire là :
Code boucles.c : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 void withWhile(void) { while(1) ; } void withFor(void) { for(;;) ; } void nop() { }
Il n'y a donc pas de différence en les deux boucles.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 PS D:\Users\pgradot\Documents\C\out\Debug> objdump.exe -d .\boucles.o .\boucles.o: file format pe-i386 Disassembly of section .text: 00000000 <_withWhile>: 0: 55 push %ebp 1: 89 e5 mov %esp,%ebp 3: eb fe jmp 3 <_withWhile+0x3> 00000005 <_withFor>: 5: 55 push %ebp 6: 89 e5 mov %esp,%ebp 8: eb fe jmp 8 <_withFor+0x3> 0000000a <_nop>: a: 55 push %ebp b: 89 e5 mov %esp,%ebp d: 5d pop %ebp e: c3 ret f: 90 nop
Merci pour votre réponse
J'ai bien apprécié votre réponse.
et ceci valable pour n'importe quel compilateur ?
Autre question : Pourquoi l'accès à une variable globale demande deux fois plus de temps que d’accéder à une variable locale?
Ca faisait plusieurs fois que je voyais la question, j'ai décidé de vraiment regarder. C'était instructif pour moi. Content que ça vous serve aussiMerci pour votre réponse
J'ai bien apprécié votre réponse.
En théorie, non : le résultat n'est valable que pour ce compilateur. Comme c'est le portage de gcc pour Windows, ça doit aussi être valable pour gcc. En pratique, je pense que n'importe quel compilateur un minimum intelligent sera capable de produire le même résultat (et même devrait le produire).et ceci valable pour n'importe quel compilateur ?
Comment avez-vous constaté cela ?Autre question : Pourquoi l'accès à une variable globale demande deux fois plus de temps que d’accéder à une variable locale?
Ce n'est pas possible que les variables local soit dans le registre (par info sur intel il n'y a que 4 registres pour les 'données') , mais je veux bien croire que pour une variable il l'a laisse dans un registre pour une optimisation particulière.
Sinon en général il doit faire un truc du genre :
Mais les variables sont en RAM que ça soit locale ou général.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 mov ma_variable,%eax
Bonjour,
Plus on accédè à une variable plus la probabilité qu'elle soit dans la mémoire cache augmente. (Il y a un facteur d’accélération entre 10 et 100 entre un accès en cache et un accès en RAM).
Généralement quand on active le options d'optimisation le compilo va essayer d'utiliser un maximum de registres pour effectuer les traitement sur la dites variables (facteur d’accélération entre 1 et 3 entre registre et cache L1).
EAX c'est le registre accumulateur ; il sert exclusivement à effectuer des opérations arithmétiques ou bien à passer des paramètres à l'instruction INT pour l'appel d'interruptions
oui mais pour charger la variable locale dans les registres de travail du CPU il faut qu'elle soit chargée de quelque part donc de la RAM.
Tu ne peux pas placer constammer une valeur dans EBX,ECX par exemple sinon la valeur va être écrasée au fonctionnement du CPU
Bonsoir,
Alors avantage ( 1-1 ) pour chacunAu niveau d'optimisation quelle est la différence entre : While(1){} et for(;; ){}?
- Avec la boucle for, tu tapes moins de lettres
- Avec la boucle while, c'est plus lisible
Sans rire, avant de parler d'optimisation, on pourrait parler de code lisible et maintenable, d'un code concis, de votre temps de codage et tout ça avant de parler de rapidité à l'exécution, non?
Si vous faites un code spaghetti, avec des goto partout, vous allez optimiser quoi? Si votre code est laissé à un codeur tierce et qu'il doit vous comprendre, ne gagnera-t-il pas plus de temps à refaire? (Perte de temps, d'argent, ...)
L'optimisation (dans le sens où vous en parlez) est loin d'être la chose la plus importante, je dirais qu'elle doit être présente quand on a pas ou plus le choix. Est-ce votre cas?
En même temps, si votre compilateur n'accepte pas l'une ou l'autre syntaxe, cette question ne se posera peut-être même pas
Les boucles infinies, je rajouterais, ça peut être dangereux, il faut bien connaître les conditions d'arrêt de sa boucle et si on peut éviter et bien je dirais, on optimise!
Question : Pourquoi ne pas comparer avec une boucle infinie utilisant goto ?
Bonne continuation...
Bonjour,
Sauf cas tres tres tres exceptionnel, il n'y a aucune raison de se poser une telle question.
Soit tu en es a des phases d'optimisation telles que tu en arrives ici, et dans ce cas tu sais que tu dois generer l'assembleur, et optimiser celui-ci, soit tu en a l'ecriture du programme, et ca ne sert a rien de chercher a optimiser cela.
Enfin, si c'est pour l'information, c'est toujours interessant d'etre curieux.
+1000 !Sauf cas tres tres tres exceptionnel, il n'y a aucune raison de se poser une telle question.
La différence sera au pire de quelques cycles et j'ose espérer que le contenu de la boucle sera bien plus coûteux, rendant négligeable la différence entre while et for![]()
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager