t=GetTickCount_()
For h.l = 0 To 100000*1000 : Next
j = GetTickCount_() - t : Debug j : MessageRequester("", "for next = " + Str(j) + "ms", 0)
h=0 : t=GetTickCount_()
While h <= 100000*1000 : h+1 : Wend
j = GetTickCount_() - t : Debug j : MessageRequester("", "while wend & pb = " + Str(j) + "ms", 0)
h=0 : t=GetTickCount_()
While h <= 100000*1000 : INC h : Wend
j = GetTickCount_() - t : Debug j : MessageRequester("", "while wend & asm = " + Str(j) + "ms", 0)
en compilant j'obtient :
for next = 3203ms
while wend & pb = 6109ms
while wend & asm = 6109ms (pareil que l'autre)
et avec l'exe j'obtient :
for next = 359ms
while wend & pb = 578ms
while wend & asm = 396ms
---------------------------
jaPBe - Erreur du compilateur !
---------------------------
Line 11: 'H' is not a valid operator
---------------------------
OK
---------------------------
j'ai oublier de precisier, il faut activer l'asm inline! (je sais pa comment on fait avec japbe, j'utilise l'editeur d'origine moi)
mais sa confirme qd meme, maintenant je svais essayer d'utiliser for next au lieu des autre boucle (qd c'est possible)
test 1 = 1750 ms
test 2 = 3328 ms
test 3 = 3344 ms
avec l'exe
test 1 = 219 ms
test 2 = 297 ms
test 3 = 219 ms
Cpu athlon 2400 xp+
Il semble que le test1 = test 3, ce doit être du au compilateur ( comment fait on une boucle for next en asm ! ce doit être pour cela que step n'accepte que des constantes )
; boucle for next
; For i = 0 To 10
MOV dword [v_i],0 ; la variable i se nomme en asm v_i (car c'est une variable globale dans cet exemple),
; on met i à 0 avec l'instruction MOV, le dword signifie que c'est
; un long donc sur 4 octets
_For1: ; _For1: est un label ou étiquette qui permet d'avoir un repère pour faire des sauts
MOV eax,10 ; on met la valeur 10 dans le rgistre eax (accumulateur)
CMP eax,dword [v_i] ; CMP --> compare la valeur de eax avec celle de i; cette instruction
; va permettre de placer certains drapeaux du microprocxesseurs avec
; les valeurs correspondantes (Drapeaux AF CF OF PF SF ZF)
JL _Next2 ; JL --> Jump if Less (signed) ce qui veut dire saute si inférieur (nombre signé)
; saute à l'étiquette _Next2 si eax est inférieur au contenu de i ce qui signifie
; que i vaudra 11 à la fin de la boucle for i = 0 to 10
; si eax est supérieur à i; l'instruction JL _Next2 est ignorée
; et on continue avec l'instruction suivante
; b = i +1
MOV ebx,dword [v_i] ; on charge dans le registre ebx le contenu de i (dword = sur 4 octets)
INC ebx ; INC --> on incrémente ebx de 1
MOV dword [v_b],ebx ; on sauvegarde la variable b avec la valeur de ebx soit i + 1
; Next i
_NextContinue2: ; _NextContinue2 est une étiquette
INC dword [v_i] ; on incrémente i de 1 directement en mémoire avec INC sans passer par un registre
JMP _For1 ; JMP --> JUMP = saute à l'étiquette _For1 (on continue la boucle)
_Next2:
Paneric a écrit :Denis,
je me suis amusé avec ton exemple:
Paneric
En fait c'est pas mon exemple mais le code généré par le compilateur PureBasic auquel j'ai ajouté des commentaires.
Effectivement on peut toujours améliorer le code asm mais il ne faut pas oublier que le compilateur doit s'adapter à un grand nombre de possibilités; ce code est donc un code pas forcément le plus rationnel mais parfaitement fonctionnel et qui dans bien des cas n'est pas critique en terme de vitesse. Si on veut améliorer, il faudra 'reprendre le code' asm à la main.
je suis étonné de voir que les resultats sont diffent entre 'while pb' et 'while asm' etant donné que le compilateur genere exactement le meme code pour les 2 (et oui, l'asm sert a rien ici ). Voir le fichier purebasic.asm en mode /COMMENTED.