Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
2520 connectés 

 


 Mot :   Pseudo :  
 
 Page :   1  2  3
Page Suivante
Auteur Sujet :

Puissances de 2 et optimisation de poils de nez

n°218565
joce
Architecte / Développeur principal
"BugHunter"
Posté le 22-09-2002 à 20:24:40  profilanswer
 

Reprise du message précédent :
up :D


---------------
Protèges carnets personnalisés & accessoires pour bébé
mood
Publicité
Posté le 22-09-2002 à 20:24:40  profilanswer
 

n°219042
exo_
Posté le 23-09-2002 à 21:11:56  profilanswer
 

joce a écrit a écrit :

 
 
Tient essaie voir :
 

Code :
  1. int expDeux(int x) {
  2.   int result=0; 
  3.   int k=0;
  4.   while (x>15) { 
  5.     x>>=4; 
  6.     k+=4; 
  7.   } 
  8.   if (x & 8)
  9.     result = k+4;
  10.   else if (x & 4)
  11.     result = k+3;
  12.   else if (x & 2)
  13.     result = k+2;
  14.   else
  15.     result = k+1;
  16.   return result; 
  17. }


 




 
Ah oui déjà, ça a une meilleure tête. A vue de nez, c'est tout à fait correct contrairement au truc de l'initialisation par division avec 16, qui en toute logique merdait lamentablement dès que l'on dépassait 16 :) En effet, par exemple, 256/16=16 et donc le bit le plus fort est dans le 8ème octet, ce qui pour des entiers codés sur 4 octets est un peu surprenant :ouch: M'enfin la nouvelle solution est superbe mais la grosse boucle du départ, c'est pas terrible. Alors certes le décalage est sur 4 bits au lieu de 1 pour ma solution donc a priori c'est super, moins d'itérations à faire. Mais avec l'addition de 4 (qui est vraisemblablement moins rapide que ma bête incrémentation), je ne suis pas certain que le gain de performance existe. D'ailleurs avec un petit time et 2^31*2^31 appels, c'est impossible de voir la différence. Et je ne mentionne même pas les tests en sortie de l'itération. Donc pour conclure, ce n'est pas la solution magique que j'attendais... Mais merci quand même, bel effort  ;)  
 
Quant aux solutions avec écriture en dur de 36000 valeurs, c'est pas beau (je suis très chiant et j'en suis fier).

n°219058
joce
Architecte / Développeur principal
"BugHunter"
Posté le 23-09-2002 à 21:47:57  profilanswer
 

exo_ a écrit a écrit :

 
 
Ah oui déjà, ça a une meilleure tête. A vue de nez, c'est tout à fait correct contrairement au truc de l'initialisation par division avec 16, qui en toute logique merdait lamentablement dès que l'on dépassait 16 :) En effet, par exemple, 256/16=16 et donc le bit le plus fort est dans le 8ème octet, ce qui pour des entiers codés sur 4 octets est un peu surprenant :ouch: M'enfin la nouvelle solution est superbe mais la grosse boucle du départ, c'est pas terrible. Alors certes le décalage est sur 4 bits au lieu de 1 pour ma solution donc a priori c'est super, moins d'itérations à faire. Mais avec l'addition de 4 (qui est vraisemblablement moins rapide que ma bête incrémentation), je ne suis pas certain que le gain de performance existe. D'ailleurs avec un petit time et 2^31*2^31 appels, c'est impossible de voir la différence. Et je ne mentionne même pas les tests en sortie de l'itération. Donc pour conclure, ce n'est pas la solution magique que j'attendais... Mais merci quand même, bel effort  ;)  
 
Quant aux solutions avec écriture en dur de 36000 valeurs, c'est pas beau (je suis très chiant et j'en suis fier).




tu peux squisser l'incrémentation par quatre et faire un multiplication par 4 en sortie si tu veux :D
sinon je suis d'accord pour les tests en sortie pas glop, mais je pensais que le fait de décaler 4 par 4 compensait largement


---------------
Protèges carnets personnalisés & accessoires pour bébé
n°221113
Musaran
Cerveaulté
Posté le 27-09-2002 à 04:54:12  profilanswer
 

Ça dépends trop des performances de chaque instruction, il y a 36'000 façons de faire.
Je n'en propose que 3:

Code :
  1. #include <stdio.h>
  2. #include <assert.h>
  3. //type d'élément pour la table de lookup, au choix
  4. typedef char lookup_t; //pas de multiplication de l'indice, moins encombrant
  5. //typedef int lookup_t; //pas de promotion pour le calcul
  6. //table de lookup byte -> log2up
  7. lookup_t log2uplk[256]= {
  8. 1,
  9. 2,
  10. 3,3,
  11. 4,4,4,4,
  12. 5,5,5,5,5,5,5,5,
  13. 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
  14. 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  15. 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
  16. 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
  17. };
  18. //descente binaire par adresses, puis lookup octet
  19. int log2upA(int x) {
  20. const unsigned short*const pshrt= (unsigned short*)&x;
  21. const unsigned char *const pbyte= (unsigned char *)&x;
  22. if(pshrt[1])
  23. /**/        if(pbyte[3]) return 3*8 + log2uplk[pbyte[3]];
  24. /**/        else         return 2*8 + log2uplk[pbyte[2]];
  25. else
  26. /**/        if(pbyte[1]) return 1*8 + log2uplk[pbyte[1]];
  27. /**/        else         return 0*8 + log2uplk[pbyte[0]];
  28. }
  29. //idem, via indice intermédiaire
  30. int log2upB(int x) {
  31. const unsigned short*const pshrt= (unsigned short*)&x;
  32. const unsigned char *const pbyte= (unsigned char *)&x;
  33. int k= pshrt[1] ? pbyte[3]?3:2 : pbyte[1]?1:0 ;
  34. return k*8 + log2uplk[pbyte[k]];
  35. }
  36. //macros, pas d'appel de fonction
  37. #define BYTENOF(x,n) ( ((unsigned char *)&x)[n] )
  38. #define SHRTNOF(x,n) ( ((unsigned short*)&x)[n] )
  39. #define CPT(x,n) ( n*8 + log2uplk[BYTENOF(x,n)] )
  40. #define LOG2UP(x) SHRTNOF(x,1) ? (BYTENOF(x,3)?CPT(x,3):CPT(x,2)) : (BYTENOF(x,1)?CPT(x,1):CPT(x,0))
  41. int main(){
  42. assert(sizeof(short)==2*sizeof(char )); //1 short fait 2 char
  43. assert(sizeof(int  )==2*sizeof(short)); //1 int   fait 2 short
  44. //assert little endian; //comment faire ?
  45. int i;
  46. for(;;){
  47.  scanf("%d",&i);
  48.  printf("\t" );
  49.  printf(" %2d", log2upA(i) );
  50.  printf(" %2d", log2upB(i) );
  51.  printf(" %2d", LOG2UP (i) );
  52.  puts("" );
  53. }
  54. return 0;
  55. }


Message édité par Musaran le 27-09-2002 à 04:55:44

---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
mood
Publicité
Posté le   profilanswer
 

 Page :   1  2  3
Page Suivante

Aller à :
Ajouter une réponse
 

Sujets relatifs
[PHP] - [MySQL] - Optimisation de SELECT COUNT(*)[Oracle] Optimisation des paramètres Oracle, update de masse
Mon applet est une usine a gaz [optimisation et solution inside]Optimisation d'une requête. Laquelle choisiriez-vous ?
MySql - Optimisation - Champ indexé AND Champ pas indexé[PHP] Optimisation pour un template
[forum] création / optimisation[php] optimisation?
Au fait, au sujet du pb d'optimisation d'un programme de gravure de CD[Optimisation Mysql] Qui peut m'aider ?
Plus de sujets relatifs à : Puissances de 2 et optimisation de poils de nez


Copyright © 1997-2025 Groupe LDLC (Signaler un contenu illicite / Données personnelles)