Oh bon sang, de la dubstep…
Un jour, nous reviendrons aux bonnes vieilles musiques éléctro.
http://www.youtube.com/watch?v=17FAFpmNIWA
J'en suis persuadé.
C'est pas juste, c'est pas la même ambiance. Vous ne voulez pas que je sorte une musique de Bioshock Infinite tant que l'on y est ?
J'ai réussi à lui faire générer autre chose qu'un saut conditionnel avec un fonction (un peu bidon je l'admet) où les deux résultats de l’expression conditionnelle sont des constantes, voici la première version de la fonction (avec un if/else) et le code assembleur correspondant:
int f1(int n)
{
if(n>10) return 15;
else return 25;
}
00B06ADE cmp dword ptr [ebp+8],0Ah
00B06AE2 jle 00B06AED
00B06AE4 mov eax, 0Fh
00B06AE9 jmp 00B06AF2
00B06AEB jmp 00B06AF2
00B06AED mov eax, 19h
00B06AF2 (début de l'épilogue de la fonction)
Ici on effectue première une comparaison de n (adresse pointée par ebp+8 sur la pile) et de 10, si n est inférieur à 10 on saute à l'adresse 00B06AED qui contient une instruction mov qui met le résultat 25 dans eax, autrement on met le résultat 15 dans eax et on saute directement à l'adresse 00B06AF2 (en revanche j'ignore pourquoi il y a deux instructions jmp 00B06AF2 qui se suivent) qui correspond au début de l'épilogue de la fonction. Bref c'est un branchement, il y a bien un saut conditionnel.
Deuxième version avec une expression conditionnelle maintenant :
int f2(int n)
{
return n>10 ? 15 : 25;
}
xor eax,eax
cmp dword ptr [ebp+8],0Ah
setle al
sub eax,1
and eax,0FFFFFFF6h
add eax,19h
Pour cet exemple imaginons qu'on a passé 11 comme argument, on met d'abord le registre eax à 0 (xor eax, eax), ensuite on effectue une comparaison entre n (qui est égal à 5 donc) et 10 (cmp dword ptr [ebp+8],0Ah) pour mettre les bits de flags comme il faut, ensuite l'instruction setle al met l'octet de poids faible de eax (al) à 0 car il est supérieur à 10 (l'instruction SETx met un octet à 1 si une condtion est vrai, à 0 si elle est fausse, on remplace x par une condition, ici "le" pour less or equal), ensuite on lui soustrait 1 (sub eax,1), il contient donc -1 maintenant.
A ce stade on a donc -1 (en complément à deux, que des bits à 1) dans le registre eax, on effectue un ET bit à bit de eax et de la constante FFFFFFF6h (-10 en complément à deux, à noter que cela correspond à la différence des deux résultats, 15-25), vu qu'il n'y que des 1 dans eax, eax contient alors la valeur -10, on lui ajoute alors 25 (add eax, 19h) et eax qui contenait -10 contient alors 15 qui est la bonne valeur de retour car si n>10 on retourne 15 conformément à ce qui est écrit dans la fonction.
Si n avait été inférieur à 10, suite aux instructions "setle al" et "sub eax, 1" il aurait contenu 0 (que des 0 en binaire donc) et l'instruction "and eax,0FFFFFFF6h" aurait donné 0, en ajoutant 25 on aurait 25 le résultat correct si n<10.
Bref voila un exemple où en utilisant une expression conditionnelle plutôt qu'un if, le compilateur génère du code sans branchement.
" ensuite on effectue une comparaison entre n (qui est égal à 5 donc) "
Je voulais dire 11. ![]()
ogod, c'est à moitié incompréhensible, mais il a bien supprimé les jumps avec l'expression conditionnelle, c'est passionnant en fait d'aller voir ce qui se passe dans l'assembleur. ![]()
" c'est passionnant en fait d'aller voir ce qui se passe dans l'assembleur.
"
C'est l'une des raisons pour laquelle il est utile d'apprendre l'assembleur aujourd'hui, pour essayer d'aider le compilateur à générer du meilleur code assembleur, on peut aussi directement écrire de l'assembleur inline dans le programme mais on perd la portabilité vers d'autres architectures.
Pour l'expression conditionnelle à noter aussi que si on fait un truc en plus que de simplement renvoyer un résultat, genre:
int f2(int n)
{
int t=0;
return n>10 ? t++, 15 : 25;
}
Ici on pourra pas avoir un transfert de données conditionnel avec CMOV (ni un truc comme le code assembleur que j'ai donné en exemple) et on sera obligé d'utiliser un branchement.
Normalement c'est pareil si on fait un truc qui pourrait renvoyer une exception (genre déréférencement de pointeur nul), car en plus de renvoyer le résultat il faut jeter une exception donc il y a besoin d'un branchement.
Il y aussi le cas de l'utilisation d'un switch au lieu d'une suite de if/else qui est assez fascinant mais il est tard et j'ai un film à regarder. ![]()
http://derpicdn.net/media/W1siZiIsIjIwMTMvMDgvMDQvMTdfMDhfMjFfNjI3XzM5MTIwMV9fc2FmZV9zcGFnaGV0dGlfYnJvbnljb25fY2FwcGVyZ2VuZXJhbCJdXQ/391201__safe_spaghetti_bronycon_cappergeneral.jpeg image prise dans une poney convention.
"Ici on pourra pas avoir un transfert de données conditionnel avec CMOV (ni un truc comme le code assembleur que j'ai donné en exemple) et on sera obligé d'utiliser un branchement.
Normalement c'est pareil si on fait un truc qui pourrait renvoyer une exception (genre déréférencement de pointeur nul), car en plus de renvoyer le résultat il faut jeter une exception donc il y a besoin d'un branchement. "
Ah okay... Il en faut peu pour passer à côté de l'optimisation, en fait. ![]()
Des conditions ternaires ![]()
Ah, vous n'avez pas ça en caml? ![]()
Eh, les conditions ternaires c'est en C.
Au lieu de faire un code lisible est beau du genre
if (n!=45)
{
x=(-1);
}
else
{
x=1;
}
on fait :
x= (n!=45) ? -1 : 1 ;
C'est moche ![]()
La lisibilité est souvent le reproche que les gens font aux expression conditionnelles. Cela dit je trouve ça plus beau parfois, genre la fonction max on l'écrit souvent comme ça:
return x >= y ? x : y;
Je trouve ça mieux qu'avec les if/else.
Mes yeux saignent ![]()
Surtout qu'il n'y a généralement pas de coloration syntaxique pour ce genre d'expressions ![]()
demande de ban ![]()
Vous vous rendrez bien vite compte que les expressions en ligne sont plus simples à lire. Si vraiment elle est compliqué, elle ne le sera pas moins avec des if.
Dans les deux cas, cela nécessite un commentaire.
silox-, son pseudo a été exclu du forum ![]()
Peux envoyer quand des messages avec ?
" Vous vous rendrez bien vite compte que les expressions en ligne sont plus simples à lire. Si vraiment elle est compliqué, elle ne le sera pas moins avec des if.
Dans les deux cas, cela nécessite un commentaire. "
Aerdaiis, mauvais programmeur Java et expert en CSS, a parlé, l'affaire est close. ![]()
Pocoio, chômeur professionnel a parlé.
Mais où est donc mon pécari ?
Sans emploi, pas chômeur, GROSSE différence. ![]()
C'est ta mère qui m’entretient. ![]()