Comment inverser les bits d'un octet ? - ASM - Programmation
Marsh Posté le 02-09-2004 à 17:09:58
si ton octet est dans al et que eax est utilisable :
xor ah, ah |
le résultat est dans ah
Marsh Posté le 02-09-2004 à 17:16:23
Ah oué voila c'est tres long
Y'a vraiment rien de plus simple ?
EDIT : Merci en tout cas
Marsh Posté le 02-09-2004 à 17:49:47
AthlonSoldier a écrit : Ah oué voila c'est tres long |
de rien
long ?
t'as déjà fait du RISC ? ça c'est ce que j'appelle long.
Cette boucle est déroulée, enroulé avec un loop ça ferait 6 lignes. C'est pas énorme. Il y a des bonnes méthodes pour inverser les octets d'un WORD ou d'un DWORD, mais pas les bits, ou alors c'est un truc tordu que je connais pas.
Marsh Posté le 02-09-2004 à 17:51:13
Si c'est juste les bits d'un octet, je suggère soit la table de lookup à 256 entrées, soit une table à 16 entrées mais on fait 2 lookup dedans, une fois pour les 4 bits de poids faible et une fois pour ceux de poids fort
Marsh Posté le 02-09-2004 à 17:53:58
AthlonSoldier a écrit : C'est à dire ? |
Tu crée en mémoire une fois pour toute un tableau à 256 entrées représentant la transformation que tu veux faire. Après il suffit de faire ( exemple en C ) :
Code :
|
Marsh Posté le 02-09-2004 à 18:03:27
Je pense que c'est tres lent ca, vu qu'il y a acces mémoire
Quelqu'un peut dire a vue d'oeuil si c plus rapide que de faire une boucle en asm (celle de jesus_christ) ?
Marsh Posté le 02-09-2004 à 18:34:40
Une fois le tableau en cache ce qui n'est vraiment pas difficile pour un tableau de 256 octets, c'est certainement beaucoup plus rapide que la boucle vue ci dessus. Le seul point litigieux serait pour le cas ou le resultat obtenu influe sur la prediction de branchement dans les quelques instructions suivantes.
Marsh Posté le 02-09-2004 à 19:31:29
ouais l'option de kris semble la meilleure, 256 octets ça rentre dans le L1. T'aura un AGI stall à chaque accès mais ça doit être + rapide qu'une boucle qui tourne 8 fois.
Marsh Posté le 03-09-2004 à 00:22:17
jesus_christ a écrit : si ton octet est dans al et que eax est utilisable :
|
on peut chippoter un peu et preferer utiliser
rol al,1
rcr ah,1
ca evite l'instruction adc, puisque la rotation passe par le carry
Marsh Posté le 03-09-2004 à 00:29:00
prorel a écrit : on peut chippoter un peu et preferer utiliser |
Merci
Marsh Posté le 03-09-2004 à 11:26:15
prorel a écrit : on peut chippoter un peu et preferer utiliser |
bien vu !!! ça shift et ajoute le bit de poids faible en une instruction
je mettrai alors
shl al,1 |
vu que la première rotation ne sert à sortir le bit de poids fort, shift est suffisant et + rapide que la rotation sur la plupart des cpu (tous ?).
Marsh Posté le 03-09-2004 à 16:42:58
exact, rcr ne prend qu'1 cycle (a partir du p1), alors que shl en prend 3
bravo!
Marsh Posté le 03-09-2004 à 17:02:58
prorel a écrit : exact, rcr ne prend qu'1 cycle (a partir du p1), alors que shl en prend 3 |
euh c'est pas le contraire ?
Marsh Posté le 03-09-2004 à 17:11:14
nan d'apres le bouquin, c'est bien "rcr reg,1" qui prend 1 cycle
Marsh Posté le 03-09-2004 à 19:40:36
j'ai vérifié dans mon bouquin (JB Emond) et les deux opérations
rcr reg, 1 |
prennent toutes les 2 un seul cycle.
Ca serait trop étrange qu'un rotate (peu utilisé) prennent plus de place qu'un shift (très utilisé)
Marsh Posté le 03-09-2004 à 19:51:34
pour quel proc??
j'ai pas le p4
atention il faut aussi tenir compte de la mise a jour du reg status,
d'apres ma doc
rcr met a jour carry et overflow, alors que shl met a jour Overflow, sign,zero, aux carry, parity, et carry
ca vient ptet de là??
Marsh Posté le 03-09-2004 à 20:27:17
Je viens de me creuser la cervelle... ça m'arrive
J'ai donc trouver une autre technique. Celle-ci est beaucoup plus rapide. Donc... (c) Christophe Gossa, Tous droits réservés.
En fait on va décomposer l'opération successivement. En 3 étapes :
- Permutation des 2 quartets (2x4 bits)
- Permutation des 4 paire de bits (4x2 bits)
- Permutation finale des 8 bits (8x1 bits)
Voici un exemple : On ne verra que la représentation des 8 bits (0 à 7)
|
Total des instructions :
- 6x décalages
- 6x masques (ET)
- 6x OU
Marsh Posté le 03-09-2004 à 20:34:10
hum
je ne vois pas bien ton truc
pour que ca marche tu dois rajouter les masquage des bits inutiles, sinon avec tes OU tu vas avoir des 1 partout
Marsh Posté le 03-09-2004 à 20:43:49
Petit code vite fait pour illustrer avec l'explication...
Code :
|
Marsh Posté le 03-09-2004 à 20:53:16
Résultat sur un Barton :
10 cycles en boucle.
On peut dire que le re-ordering du cpu est assez efficace, mais le code est plus efficace pour du 2 canaux que pour le 3 canaux des amd.
Marsh Posté le 03-09-2004 à 22:03:34
christophe_d13 a écrit : Résultat sur un Barton : |
beau travail
et le programme "classique" il prend combien de cycles??
Marsh Posté le 03-09-2004 à 23:35:41
je débarque peut etre avec mes vieux souvenirs d assembleur zx80 mais.. un XOR ca existe pas sur ASMx86?
EDIT: faites pas attention j avais compris autre chose par "inverser les bits d un octet": mettre des O a la place des 1 et des 1 a la place des 0.. j avais pas lu la question en entier.. Je vais dormir
Marsh Posté le 03-09-2004 à 23:36:33
deumilcat a écrit : je débarque peut etre avec mes vieux souvenirs d assembleur zx80 mais.. un XOR ca existe pas sur ASMx86? |
si, mais tu veux le mettre ou??
Marsh Posté le 03-09-2004 à 23:38:29
prorel a écrit : si, mais tu veux le mettre ou?? |
EDIT: faites pas attention j avais compris autre chose par "inverser les bits d un octet": mettre des O a la place des 1 et des 1 a la place des 0.. j avais pas lu la question en entier.. Je vais dormir
Marsh Posté le 03-09-2004 à 23:41:20
deumilcat a écrit : je débarque peut etre avec mes vieux souvenirs d assembleur zx80 mais.. un XOR ca existe pas sur ASMx86? |
C'est NOT ca
Marsh Posté le 04-09-2004 à 00:04:35
Résultat de la comparaison :
Code :
|
25 cycles !
Code :
|
24 cycles !
Code :
|
10 cycles !
Code :
|
3 cycles !
Sous forme de mini-tableau
#1 =========================
#2 ========================
#3 ==========
#4 ===
Toutes ces mesures sont faites dans une boucle de 1.000.000. Donc le code est dans le cache et se trouve paralélisé.
Marsh Posté le 04-09-2004 à 00:10:29
dans le cas 2 tu n'a pas besoin du "adc ah,0"
mais bon, c'est chippoter
c'est clair que la table c'est le mieux si c'est juste avec 256 octets et qu'il y a un traitemnt lourd derriere
Marsh Posté le 04-09-2004 à 00:16:52
prorel> Tout dépend de l'usage. Dans le cas où la routine est appelé assez rarement, ou bien que juste avant le cache est altéré, il faudra choisir la meilleure routine.
Les pénalités sur AthlonXP+nForce2 si les données sont en :
RAM - >180 cycles
L2 - 20 cycles
L1 - 3 cycles.
Marsh Posté le 04-09-2004 à 00:20:57
on peut faire un compromis
lancer la premiere fois le prog 1 qui charge la table, et les appels suivants on passe par la table
Marsh Posté le 04-09-2004 à 00:31:52
prorel> Oui, mais si pour les appels suivants la table n'est pas dans L1 ? On passe à 20 cycles !
A l'inverse si on sait que l'on parcourera toute la table, on peut faire un software-block-prefetch en lisant simplement les offsets 0, 32, 64, 96... jqà 224 pour un ligne de 32 octets et 0, 64, 128 et 192 pour une ligne de cache de 64 octets.
Marsh Posté le 04-09-2004 à 00:34:50
Il n'y a jamais de meilleures méthodes, juste des compromis.
Bonne nuit !
Marsh Posté le 04-09-2004 à 01:07:57
C'est gentil d'essayer de faire le code le plus optimisé pour ma simple question
Marsh Posté le 04-09-2004 à 21:50:59
je voudrais pas chipoter mais un rotate 4 sur al dans la méthode de chris (jolie d'ailleurs ) au lieu de la 1ere étape ça serait pas + rapide ?
et puis dans la méthode #2 il n'y a pas de adc, sinon le code est faux.
Marsh Posté le 05-09-2004 à 09:16:58
Bien vu mais bon c'est un premier jet, je n'ai pas cherché à faire le plus rapide. Juste expliquer en ASM ma méthode.
Up> Et puis il fallait vraiment voir les 3 étapes. Mais ceci dit en ajoutant la rotation, on gagne 2 cycles. soit 8 cycles seulement.
Il est encore posible d'améliorer le code... D'après mon analyse je pense que l'on peut tomber le nombre de rotation à 3 à cause de la récurence et il doit être possible de grouper l'étape 1 et 2.
Up #2> Et bien c'est fait, 7 cycles seulement, simplement en analyse.
Le code et l'explication
Code :
|
Aucune optimisation de bas niveau, juste une reflexion sur l'algo.
Donc, 7 cycles.
Marsh Posté le 02-09-2004 à 16:53:56
Salut,
J'aimerai par exemple passer de 01110001 à 10001110.
C'est à dire que le 1er bit se retrouve en 8ieme position, le 2nd en 7 ieme etc...
J'ai bien réfléchis et a pars faire un algo assez long je vois pas trop (avec des ror, and etc... et surtout en se servant de 2 registres (j'aimerai en avoir qu'un)).
Quelqu'un a une idée ?