vinc1008881
Messages postés257Date d'inscriptiondimanche 22 août 2004StatutMembreDernière intervention29 septembre 2010
-
24 juil. 2006 à 19:58
BruNews
Messages postés21040Date d'inscriptionjeudi 23 janvier 2003StatutModérateurDernière intervention21 août 2019
-
5 août 2006 à 00:02
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.
BruNews
Messages postés21040Date d'inscriptionjeudi 23 janvier 2003StatutModérateurDernière intervention21 août 2019 5 août 2006 à 00:02
Il y a 2 pipelines sur Pentium.
; eax échange ecx
mov edx, eax
mov eax, ecx ; 1er cycle fini, pas de pénalité car EAX
nop ; surement autre chose à faire dans le prog, mais bon...
mov ecx, edx
Michael Abrash a écrit des chapitres passionnants sur le sujet, s'y reporter.
zeratul67
Messages postés97Date d'inscriptionmardi 9 avril 2002StatutMembreDernière intervention11 mai 2008 4 août 2006 à 16:39
C'est vrai que pour les débutants, cela peut induire en erreur. Malgré tout, les commentaires peuvent être intéressants, avec entre autre l'URL donnée par vecchio56 et les information sur la façon d'écrire de l'ASM dans du code C (les deux syntaxe différentes).
Finalement, histoire ce clore au cas où tout cela serait supprimé, qu'est-ce qui est le plus rapide, sans utiliser l'ASM ? Les mov avec variable temporaire, les xor ?
J'ai également un peu de mal à te comprendre BruNews, la série de mov qui permet l'échange est parallelizable ?!
BruNews
Messages postés21040Date d'inscriptionjeudi 23 janvier 2003StatutModérateurDernière intervention21 août 2019 4 août 2006 à 16:03
Ce genre de "source" est à oublier, ne peut qu'induire un débutant en erreur.
L'optimisation asm ne vaut que si la fonction est complet en asm, autrement c'est tout le contraire qui est obtenu. Il est impossible de savoir si le compilo a créé des variables sur pile ou si les valeurs sont tenues en registre, en ce cas des PUSH POP sont une totale aberration quand 3 MOV suffisaient.
XCHG est obsolète depuis le 486 et à bannir depuis le pentium avec lequel les MOV sont parallélisables.
Cette ineptie disparaitra samedi soir au plus tard.
vecchio56
Messages postés6535Date d'inscriptionlundi 16 décembre 2002StatutMembreDernière intervention22 août 201014 28 juil. 2006 à 05:04
En général quand on code en C, on se moque des flags du CPU
Mais dans ton exemple ya pas d'overflow a mon avis, car 0xFFFFFFFE représente -2 (donc a+b=0 et non 1)
vinc1008881
Messages postés257Date d'inscriptiondimanche 22 août 2004StatutMembreDernière intervention29 septembre 20103 27 juil. 2006 à 22:36
j'en sais rien, peut-etre que sa marche avec toute les valeurs, mais ce que je peux dire c'est que le flag of du registre flags du CPU sera peut-etre à 1 à cause de cet overflow.
cs_aardman
Messages postés1905Date d'inscriptionmercredi 22 janvier 2003StatutMembreDernière intervention17 septembre 20123 27 juil. 2006 à 20:14
y'a un overflow... mais ca marche ? c'est un peu contradictoire.
Pour quel couple de valeur (par exemple) cette technique ne fonctionne pas ?
vinc1008881
Messages postés257Date d'inscriptiondimanche 22 août 2004StatutMembreDernière intervention29 septembre 20103 27 juil. 2006 à 19:30
ouais ça marche mais c'est pas tres propre l'overflow...mieux vieux utiliser un xor, en plus c'est plus rapide.
vecchio56
Messages postés6535Date d'inscriptionlundi 16 décembre 2002StatutMembreDernière intervention22 août 201014 27 juil. 2006 à 19:16
int a = 0xFFFFFFFE;
int b = 0x2;
a = a + b;
b = a - b;
a = a - b;
Ca marche très bien chez moi
vinc1008881
Messages postés257Date d'inscriptiondimanche 22 août 2004StatutMembreDernière intervention29 septembre 20103 27 juil. 2006 à 19:03
t'as risque de overflow avec cette méthode.
int a = 0xFFFFFFFE
int b = 0x2
a+b = 1 ;-)
apres travailler avec des nombre codé sur 8 octet c'est trop lent
cs_aardman
Messages postés1905Date d'inscriptionmercredi 22 janvier 2003StatutMembreDernière intervention17 septembre 20123 27 juil. 2006 à 18:17
Salut,
Dans le meme genre que xor, mais avec des additions/soustractions:
a = a + b;
b = a - b;
a = a - b;
cs_neria
Messages postés319Date d'inscriptionvendredi 21 février 2003StatutMembreDernière intervention16 février 2009 26 juil. 2006 à 09:54
Je précise que la syntaxe dans #ifdef __GNUC__ est en fait la syntaxe AT&T qui est celle par défaut sous gcc (mais rien ne vaut la syntaxe intel :p).
nicolas66
Messages postés116Date d'inscriptionmercredi 25 décembre 2002StatutMembreDernière intervention 4 janvier 2009 25 juil. 2006 à 22:46
Arf c'est déjà pas si mal :p.
vecchio56
Messages postés6535Date d'inscriptionlundi 16 décembre 2002StatutMembreDernière intervention22 août 201014 25 juil. 2006 à 19:01
Portable c'est toi qui le dit. Il me semble que ton code ne compilera que sur une architecture x86
nicolas66
Messages postés116Date d'inscriptionmercredi 25 décembre 2002StatutMembreDernière intervention 4 janvier 2009 25 juil. 2006 à 18:37
Je ne pensais pas que ce simple morceau de code lancerait une polémique aussi grande. Je tiens simplement à dire que ce programme n'était là que pour montrer qu'on peut écrire de l'assembleur en ligne avec du code C++ et de rendre portable le tout. Je n'ai pas vocation à être un as de l'assembleur.
cs_eRoZion
Messages postés241Date d'inscriptionvendredi 23 mai 2003StatutMembreDernière intervention 8 octobre 20071 25 juil. 2006 à 16:23
Merci vecchio pour le lien wiki.
C'est incroyablement logique mais fallait y penser!
cs_thebigbang
Messages postés196Date d'inscriptionvendredi 21 décembre 2001StatutMembreDernière intervention25 juillet 2006 25 juil. 2006 à 13:57
vecchio56, tu auras été plus rapide que moi :)
cs_thebigbang
Messages postés196Date d'inscriptionvendredi 21 décembre 2001StatutMembreDernière intervention25 juillet 2006 25 juil. 2006 à 13:56
si tu veux faire de l'assembleur, xchg me paraît la meilleure solution pour échanger deux variables, plutôt que d'utiliser la pile.
Pour ce qui est des xor, tu peux faire ça pour échanger a et b :
a <- xor(a,b)
b <- xor(a,b)
a <- xor(a,b)
Pour échanger eax et ecx :
xor eax, ecx
xor ecx, eax
xor eax, ecx
Peut être que xchg fonctionne comme ça ?
vecchio56
Messages postés6535Date d'inscriptionlundi 16 décembre 2002StatutMembreDernière intervention22 août 201014 25 juil. 2006 à 13:55
zeratul67
Messages postés97Date d'inscriptionmardi 9 avril 2002StatutMembreDernière intervention11 mai 2008 25 juil. 2006 à 11:33
ces petites codes sont intéressants pour les débats qu'ils provoquent, mais pas directement pour leur contenu.
Concernant "A(12)", je pensequ'il vaut mieux écrire "A = 12", c'est plus lisible, c'est compatible C ... vous voyez des avantages à A(12) ?
Pour sawper deux variables, il me semble qu'il y a une technique à base d'oppérateurs logiques (des xor peut être) qui le permet sans création de variable tampon. (je ne dit pas qu'elle a de l'intérêt ... :P)
vinc1008881
Messages postés257Date d'inscriptiondimanche 22 août 2004StatutMembreDernière intervention29 septembre 20103 25 juil. 2006 à 10:49
il me semble que ces 2 lignes veulent dire charge A dans eax et charge b dans ebx >> "a"(A), "b"(B) et charge b à partir de ebx et charge a à partir de eax >> "=a"(A), "=b"(B), ce ne suis pas sur car je comprends pas grand chose à la syntaxe at&t...
en fait pour faire le swap de 2 variable il faut pour son code 4 mov et 4 push/pop, c'est de la désoptimisation :-)
vecchio56
Messages postés6535Date d'inscriptionlundi 16 décembre 2002StatutMembreDernière intervention22 août 201014 25 juil. 2006 à 05:06
Economiser 4 octets, c'est pas vraiment le genre d'optimisation qu'on recherche en général (en l'occurence ton code est plus lent qu'un code érit en C, comme le dit vinc1008881)
Mais c'est la première partie en assembleur qui m'interpelle, surtout la fin:
# : "=a"(A), "=b"(B) // Output
# : "a"(A), "b"(B) // Input
C'est bizarre ces lignes-là, ca veut dire quoi exactement?
Pour le int A(12) c'est effectivement possible en C++, car C++ considère les types de bases comme des classes (et donc a est un objet). Cependant pas de notation pointée pour les types de base
luhtor
Messages postés2023Date d'inscriptionmardi 24 septembre 2002StatutMembreDernière intervention28 juillet 20086 24 juil. 2006 à 23:29
gcc non, mais g++ oui. C'est juste un appel au constructeur, la méthode la plus classique.
vinc1008881
Messages postés257Date d'inscriptiondimanche 22 août 2004StatutMembreDernière intervention29 septembre 20103 24 juil. 2006 à 21:52
franchement, je sais pas si j'ai loupé une page de "C for beginers" mais de comprends pas là, int A(12); ça veux dire quoi ? (gcc ne le compile pas en tout cas)
luhtor
Messages postés2023Date d'inscriptionmardi 24 septembre 2002StatutMembreDernière intervention28 juillet 20086 24 juil. 2006 à 21:17
"int A(12)" n'a rien de choquant.
vinc1008881
Messages postés257Date d'inscriptiondimanche 22 août 2004StatutMembreDernière intervention29 septembre 20103 24 juil. 2006 à 21:01
vinc1008881
Messages postés257Date d'inscriptiondimanche 22 août 2004StatutMembreDernière intervention29 septembre 20103 24 juil. 2006 à 19:58
salut, j'ai remarqué quelques trucs :
- c'est quoi ce int A(12) ??? tu voulais dire int A = 12 ?
- en géneral pour des noms de variables on met des minuscules
- tu devrais mettre asm volatile (/*instruction*/); car rien ne te dis que le compilo va respecter strictement l'ordre et meme les instruction l'interieur de asm ();
- pas simpa de modifier ebx, des plantages peuvent se produire (pour eax, je crois que il n'y a pas de danger)
- question temps, c'est pas fameux : push et pop emploient plus de cycles cpu que des mov en plus il temps faut 4 push/pop au lieu de 3 mov
- dernière remarque, l'instruction assembleur xchg existe...
CODE :
asm volatile (
mov eax, a
xchg eax, b;
mov a, eax);
5 août 2006 à 00:02
; eax échange ecx
mov edx, eax
mov eax, ecx ; 1er cycle fini, pas de pénalité car EAX
nop ; surement autre chose à faire dans le prog, mais bon...
mov ecx, edx
Michael Abrash a écrit des chapitres passionnants sur le sujet, s'y reporter.
4 août 2006 à 16:39
Finalement, histoire ce clore au cas où tout cela serait supprimé, qu'est-ce qui est le plus rapide, sans utiliser l'ASM ? Les mov avec variable temporaire, les xor ?
J'ai également un peu de mal à te comprendre BruNews, la série de mov qui permet l'échange est parallelizable ?!
4 août 2006 à 16:03
L'optimisation asm ne vaut que si la fonction est complet en asm, autrement c'est tout le contraire qui est obtenu. Il est impossible de savoir si le compilo a créé des variables sur pile ou si les valeurs sont tenues en registre, en ce cas des PUSH POP sont une totale aberration quand 3 MOV suffisaient.
XCHG est obsolète depuis le 486 et à bannir depuis le pentium avec lequel les MOV sont parallélisables.
Cette ineptie disparaitra samedi soir au plus tard.
28 juil. 2006 à 05:04
Mais dans ton exemple ya pas d'overflow a mon avis, car 0xFFFFFFFE représente -2 (donc a+b=0 et non 1)
27 juil. 2006 à 22:36
27 juil. 2006 à 20:14
Pour quel couple de valeur (par exemple) cette technique ne fonctionne pas ?
27 juil. 2006 à 19:30
27 juil. 2006 à 19:16
int b = 0x2;
a = a + b;
b = a - b;
a = a - b;
Ca marche très bien chez moi
27 juil. 2006 à 19:03
int a = 0xFFFFFFFE
int b = 0x2
a+b = 1 ;-)
apres travailler avec des nombre codé sur 8 octet c'est trop lent
27 juil. 2006 à 18:17
Dans le meme genre que xor, mais avec des additions/soustractions:
a = a + b;
b = a - b;
a = a - b;
26 juil. 2006 à 09:54
25 juil. 2006 à 22:46
25 juil. 2006 à 19:01
25 juil. 2006 à 18:37
25 juil. 2006 à 16:23
C'est incroyablement logique mais fallait y penser!
25 juil. 2006 à 13:57
25 juil. 2006 à 13:56
Pour ce qui est des xor, tu peux faire ça pour échanger a et b :
a <- xor(a,b)
b <- xor(a,b)
a <- xor(a,b)
Pour échanger eax et ecx :
xor eax, ecx
xor ecx, eax
xor eax, ecx
Peut être que xchg fonctionne comme ça ?
25 juil. 2006 à 13:55
25 juil. 2006 à 11:33
Concernant "A(12)", je pensequ'il vaut mieux écrire "A = 12", c'est plus lisible, c'est compatible C ... vous voyez des avantages à A(12) ?
Pour sawper deux variables, il me semble qu'il y a une technique à base d'oppérateurs logiques (des xor peut être) qui le permet sans création de variable tampon. (je ne dit pas qu'elle a de l'intérêt ... :P)
25 juil. 2006 à 10:49
en fait pour faire le swap de 2 variable il faut pour son code 4 mov et 4 push/pop, c'est de la désoptimisation :-)
25 juil. 2006 à 05:06
Mais c'est la première partie en assembleur qui m'interpelle, surtout la fin:
# : "=a"(A), "=b"(B) // Output
# : "a"(A), "b"(B) // Input
C'est bizarre ces lignes-là, ca veut dire quoi exactement?
Pour le int A(12) c'est effectivement possible en C++, car C++ considère les types de bases comme des classes (et donc a est un objet). Cependant pas de notation pointée pour les types de base
24 juil. 2006 à 23:29
24 juil. 2006 à 21:52
24 juil. 2006 à 21:17
24 juil. 2006 à 21:01
24 juil. 2006 à 19:58
- c'est quoi ce int A(12) ??? tu voulais dire int A = 12 ?
- en géneral pour des noms de variables on met des minuscules
- tu devrais mettre asm volatile (/*instruction*/); car rien ne te dis que le compilo va respecter strictement l'ordre et meme les instruction l'interieur de asm ();
- pas simpa de modifier ebx, des plantages peuvent se produire (pour eax, je crois que il n'y a pas de danger)
- question temps, c'est pas fameux : push et pop emploient plus de cycles cpu que des mov en plus il temps faut 4 push/pop au lieu de 3 mov
- dernière remarque, l'instruction assembleur xchg existe...
CODE :
asm volatile (
mov eax, a
xchg eax, b;
mov a, eax);
ok, j'arrete là mon réquisitoire....