Question

Je dois faire une réorganisation arbitraire d'une valeur de 7 bits (oui, je sais que je devrais utiliser une table) et je me demande s'il existe des bidouilles pour le faire.

Exemple:

// <b0, b1, b2, b3, b4, b5, b6> -> <b3, b2, b4, b1, b5, b0, b6>

// the naive way
out =
   (0x020 & In) << 5 |
   (0x008 & In) << 2 |
   (0x040 & In)      |
   (0x012 & In) >> 1 |
   (0x004 & In) >> 2 |
   (0x001 & In) >> 3;

// 6 ANDs, 5 ORs, 5 shifts = 16 ops

modifier: Je pensais à quelque chose dans le genre de this

Juste pour le plaisir et parce que j’étais AFTK, je cherche une solution brutale pour trouver des solutions de la forme:

((In * C1) >> C2) & 0x7f

Aucune solution trouvée.

Était-ce utile?

La solution

Consultez la sortie du compilateur de votre "naïf". code, cela pourrait vous surprendre. Une fois, j’ai fait quelque chose comme ça et le compilateur (VC ++ 2005) a complètement changé les valeurs de tous les ands et décalages pour les rendre plus efficaces, par exemple, je suis sûr que cela effacerait votre " (0x001 & In). > > 3 ".

Mais oui, si le remaniement est une fonction fixe, une table est probablement préférable.

Mettre à jour

Pour rire, j’ai jeté un œil à la sortie du compilateur de VC ++ 2005 ....

J'ai d'abord essayé une valeur constante pour " Dans " mais le compilateur n'a pas été dupe, il a généré ce code:

mov eax,469h

c'est à dire. complètement optimisé.

Alors ... j'ai essayé une entrée correcte et j'ai obtenu ceci:

00401D4F  mov         eax,ecx 
00401D51  and         eax,20h 
00401D54  shl         eax,3 
00401D57  mov         edx,ecx 
00401D59  and         edx,8 
00401D5C  or          eax,edx 
00401D5E  mov         edx,ecx 
00401D60  sar         edx,1 
00401D62  and         edx,2 
00401D65  or          edx,ecx 
00401D67  sar         edx,1 
00401D69  shl         eax,2 
00401D6C  and         edx,9 
00401D6F  or          eax,edx 
00401D71  and         ecx,40h 
00401D74  or          eax,ecx 

Cela fait quatre équipes, cinq ET / OU, quatre OR - pas mal pour six entrées. Probablement mieux que la plupart des gens pourraient le faire à la main.

Il est probablement également optimisé pour une exécution dans le désordre, donc il y aura moins de cycles d'horloge qu'il n'y parait. : -)

Autres conseils

La première étape semble consister à comprendre une solution mathématique et à l’optimiser.

voir ici le piratage de bits

Il existe de nombreuses méthodes de bidouillage pour les opérations courantes, c’est-à-dire pour inverser l’ordre des bits dans un mot de 32 bits (10 décales, ET et OU, AFAICR).

Dans ce cas, avec un mappage apparemment complètement arbitraire d'une entrée à l'autre, je ne vois aucun moyen de la nettoyer.

Utilisez une table de recherche:)

Avant d’optimiser, assurez-vous que votre méthode "naïve" correspond à vos intentions. Si je transforme votre code en une fonction et exécute cette boucle:

for (b=0;b<7;b++)
{
    i=1<<b;
    printf("%d: %02x -> %02x\n", b, i, shuffle(i));
}

Il produit cette sortie qui contredit les commentaires. En fait, il perd des bits.

0: 01 -> 00
1: 02 -> 01
2: 04 -> 01
3: 08 -> 20
4: 10 -> 08
5: 20 -> 00
6: 40 -> 40

Pour obtenir le mélange que vous décrivez, je le coderais comme suit:

   //    0 1 2 3 4 5 6 
   //-> 3 2 4 1 5 0 6
   (0x001 & In) << 3 |
   (0x004 & In) << 2 |
   (0x020 & In)      |
   (0x012 & In) << 1 |
   (0x008 & In) >> 2 |
   (0x020 & In) >> 5 ;
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top