PUISSANCE DE 2, VITESSE ALGO, CONCOURS (WIN32)

BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019 - 1 mars 2005 à 12:34
gnairod Messages postés 37 Date d'inscription samedi 22 novembre 2008 Statut Membre Dernière intervention 11 avril 2010 - 22 déc. 2008 à 17:22
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/29847-puissance-de-2-vitesse-algo-concours-win32

gnairod Messages postés 37 Date d'inscription samedi 22 novembre 2008 Statut Membre Dernière intervention 11 avril 2010
22 déc. 2008 à 17:22
Ben j'ai gagne.

__declspec(naked) DWORD __fastcall Puiss2SupEgal_GNairod(DWORD d) {
__asm {
cmp ecx, 80000000h
ja short sup
test ecx, ecx
jz short zero
mov eax, ecx
bsr ecx, eax
bsf edx, eax
cmp ecx, edx
je short powof2
mov eax, 1
add ecx, 1
shl eax, cl
ret
powof2:
ret
sup:
mov eax, -1
ret
zero:
xor eax, eax
ret
}
}

Plus rapide que la version de Brunews.
cs_JCDjcd Messages postés 1138 Date d'inscription mardi 10 juin 2003 Statut Membre Dernière intervention 25 janvier 2009 4
22 déc. 2008 à 17:18
houlala cette discussion date de longtemps !!
sujet passionnant... oui normalement 2^0=1

on pourrait tout refaire en 64 bits et voir qui va gagner !
je n'aurai qu'a rajouter un "if" et ca tourne !
d'ailleur au passage pour parler un peu de complexite
des algorithmes : le mien est en log(log(param))
gnairod Messages postés 37 Date d'inscription samedi 22 novembre 2008 Statut Membre Dernière intervention 11 avril 2010
22 déc. 2008 à 15:33
Brunews y a un probleme je pense.
Tu dis que la fonction doit retourne la plus proche puissance de 2 sup ou egale au param mais, lorsque i vaut 1 tu retournes 2 pourtant 1 est bien une puissance de 2. 2^0 = 1.

Non?
NitRic Messages postés 402 Date d'inscription mardi 1 mai 2001 Statut Membre Dernière intervention 15 août 2011
20 mars 2005 à 04:55
Oui mais, il faudrait `forcer` le compilateur à la mettre `inline`, parce que avec un `call` elle est très lente.

Mais sinon, félicitation !!!



~(.:: NitRic ::.)~
cs_JCDjcd Messages postés 1138 Date d'inscription mardi 10 juin 2003 Statut Membre Dernière intervention 25 janvier 2009 4
20 mars 2005 à 01:52
juste un question de if au debut, Pb de <= au lieu de < :

//--------------------------------------------
#define FLAG1 0xFFFF0000
#define FLAG2 0xFF00FF00
#define FLAG3 0xF0F0F0F0
#define FLAG4 0xCCCCCCCC
#define FLAG5 0xAAAAAAAA

unsigned the7(unsigned int d)
{
int res;
if(0 == (d & 0xFFFFFFFF)) return 0x00000000;
if(0x80000000 < d) return 0xFFFFFFFF;

d --;
res = 1;
if(d & FLAG1) { d &= FLAG1; res <<= 16; }
if(d & FLAG2) { d &= FLAG2; res <<= 8; }
if(d & FLAG3) { d &= FLAG3; res <<= 4; }
if(d & FLAG4) { d &= FLAG4; res <<= 2; }
if(d & FLAG5) { d &= FLAG5; res <<= 1; }
return res << 1;
}


celle-ci remplie-t-elle toutes les specification ?
NitRic Messages postés 402 Date d'inscription mardi 1 mai 2001 Statut Membre Dernière intervention 15 août 2011
15 mars 2005 à 05:46
Résultats:

!__inline
the7: 324506902
NitRic: 213095092
Matt67: 269217699

__inline
the7: 92350761
NitRic: 100074803
Matt67: 107929266


en `__inline`, JCDjcd nous dépasse de peu !mais! elle contient encore un bogue, ce qui l'exclus des stats.

Pour la valeur 0x80000000, elle renvoie 4294967295(-1) plutôt que de renvoyer 0x80000000 ....


Matt67, oui en effet, mais j'ignore pourquoi :|




~(.:: NitRic ::.)~
cs_Matt67 Messages postés 549 Date d'inscription samedi 6 septembre 2003 Statut Membre Dernière intervention 6 mars 2010 3
13 mars 2005 à 20:35
Bonsoir,

NitRic avec ton source ta fonction est plus rapide, avec mon source ma fonction est plus rapide ???

J'ose plus trop donner mon avis mais il me semble que la fonction de JCDjcd est assez lente.

Bonne soirée,

Matt...
Hylvenir Messages postés 364 Date d'inscription mercredi 11 février 2004 Statut Membre Dernière intervention 5 octobre 2006 2
13 mars 2005 à 20:09
La classe ;)
Bravo.
cs_JCDjcd Messages postés 1138 Date d'inscription mardi 10 juin 2003 Statut Membre Dernière intervention 25 janvier 2009 4
13 mars 2005 à 19:39
bon bon, oki



//--------------------------------------------
#define FLAG1 0xFFFF0000
#define FLAG2 0xFF00FF00
#define FLAG3 0xF0F0F0F0
#define FLAG4 0xCCCCCCCC
#define FLAG5 0xAAAAAAAA

unsigned the7(unsigned int d)
{
int res;
if(0 == (d & 0xFFFFFFFF)) return 0x00000000;
if(0x80000000 <= d) return 0xFFFFFFFF;

d --;
res = 1;
if(d & FLAG1) { d &= FLAG1; res <<= 16; }
if(d & FLAG2) { d &= FLAG2; res <<= 8; }
if(d & FLAG3) { d &= FLAG3; res <<= 4; }
if(d & FLAG4) { d &= FLAG4; res <<= 2; }
if(d & FLAG5) { d &= FLAG5; res <<= 1; }
return res << 1;
}
NitRic Messages postés 402 Date d'inscription mardi 1 mai 2001 Statut Membre Dernière intervention 15 août 2011
13 mars 2005 à 18:58
tes résultats ne sont pas bon ...

0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 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,
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, 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, 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, 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,
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, 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, 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, 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,
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, 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, 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, 10, 10,



void test_func()
{

unsigned i, a, z;

for ( a -1, i 0u; i <= 1025; i++ )
{

z = the7( i );
/*if ( z != a )
{*/
printf("%u, ", z);
/* a = z;
}*/

}

}


voilà ce que ca devrait donner normalement:

0, 2, 2, 4, 4, 8, 8, 8, 8, 16, 16, 16, 16, 16, 16, 16, 16, 32, 32, 32, 32, 32, 3
2, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 64, 64, 64, 64, 64, 64, 64, 64, 64, 6
4, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 6
4, 64, 64, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
256, 256, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512,
512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512,
512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512,
512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512,
512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512,
512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512,
512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512,
512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512,
512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512,
512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512,
512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512,
512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512,
512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512,
512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512,
512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512,
512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512,
512, 512, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 102
4, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024,
1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1
024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 102
4, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024,
1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1
024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 102
4, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024,
1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1
024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 102
4, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024,
1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1
024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 102
4, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024,
1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1
024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 102
4, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024,
1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1
024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 102
4, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024,
1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1
024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 102
4, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024,
1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1
024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 102
4, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024,
1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1
024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 102
4, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024,
1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1
024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 102
4, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024,
1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1
024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 102
4, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024,
1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1
024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 102
4, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024,
1024, 1024, 1024, 1024, 1024, 1024, 1024, 2048,






~(.:: NitRic ::.)~
cs_JCDjcd Messages postés 1138 Date d'inscription mardi 10 juin 2003 Statut Membre Dernière intervention 25 janvier 2009 4
12 mars 2005 à 22:36
//--------------------------------------------
#define FLAG1 0xFFFF0000
#define FLAG2 0xFF00FF00
#define FLAG3 0xF0F0F0F0
#define FLAG4 0xCCCCCCCC
#define FLAG5 0xAAAAAAAA

unsigned the7(unsigned int d)
{
int res;
if(0 == (d & 0xFFFFFFFE)) return 0x00000000;
if(0x80000000 <= d) return 0xFFFFFFFF;

res = 0;
if(d & FLAG1) { d &= FLAG1; res += 16; }
if(d & FLAG2) { d &= FLAG2; res += 8; }
if(d & FLAG3) { d &= FLAG3; res += 4; }
if(d & FLAG4) { d &= FLAG4; res += 2; }
if(d & FLAG5) { d &= FLAG5; res += 1; }
return res;
}
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
12 mars 2005 à 19:07
bien sûr
cs_JCDjcd Messages postés 1138 Date d'inscription mardi 10 juin 2003 Statut Membre Dernière intervention 25 janvier 2009 4
12 mars 2005 à 18:55
"Pas de table précalculée ni série de 32 'if' "


on a le droit a 6 ou 7 if ?
Hylvenir Messages postés 364 Date d'inscription mercredi 11 février 2004 Statut Membre Dernière intervention 5 octobre 2006 2
10 mars 2005 à 22:05
Brunews > Ok. J'avais mis jusqu'à maintenant de côté l'asm et le __inline (c'est pas trop mon truc l'asm).
Mais en tout cas, ça m'aura donné l'occasion d'avoir à réouvrir mes docs d'asm :)

NitRic > No problemo. Je ne fais pas non plus de GUI sous windows.

PS : Sous hpux et un vieux proc, c'est aussi ta fonction qui est plus rapide.
NitRic Messages postés 402 Date d'inscription mardi 1 mai 2001 Statut Membre Dernière intervention 15 août 2011
10 mars 2005 à 00:01
Pour le GUI, je te laisse relire les messages précédents et deviner pour quelle raison j'avais écrit ca, sinon tu risque d'attendre très longtemps après moi pour du GUI =P

Autre: 238871380
Matt67: 301855115
Hylvenir: 387281082

encore et toujours des résultats différents ...
à croire que nos PC favorises notre propre code au détriments de ceux des autres ... et je n'ai même pas mis ma fonction `__inline` ...

Une question qui restera surement sans réponse un bon moment; Pourquoi?

Au fait, BruNews à raison, prendre le code ASM généré par le compilo et le compiler dans un source C/C++ n'est _vraiment_ pas une bonne idée =P


~(.:: NitRic ::.)~
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
9 mars 2005 à 23:31
Hylvenir > j'avais déjà expliqué pourquoi, le compilo ne mettra pas direct le code dans la fonction si est asm alors que le tout petit code C est mis direct inline, la différence de perf devient donc énorme. Pour comparer vraiment faudrait écrire toute la func de test en asm.
Hylvenir Messages postés 364 Date d'inscription mercredi 11 février 2004 Statut Membre Dernière intervention 5 octobre 2006 2
9 mars 2005 à 22:51
Bonsoir, de retour sur ce thread rigolo.
J'ai branché ma fonction sur ton prog de test du dessus.
Voilà ce que j'obtiens...
c'est marrant à 3 machines, trois résultats différents.
Autre est un peu plus rapide que Matt67, mais Hylvenir est toujours un peu plus rapide. J'ai lancé plusieurs fois le test et l'ordre est toujours identique.
Pour compiler :
cl /Ox /G6 /GX performance.cpp

Par contre, quand je génère l'asm issus d'une fonction C (Matt67 par exemple) et que je l'intègre pour remplacer le C original, les performances chutent au niveau de l'ASM.
Je ne sais pas trop pourquoi.
J'attends ta GUI :)

D:\>performance.exe
2147483648

Autre: 25843818
Matt67: 27430273
Hylvenir : 23833085
ASM: 69672336


unsigned Hylvenir(unsigned n)
{
if ( n < 0x80000000 )
{
if ( n & ( n - 1 ) )
{
unsigned i 0x80000000, n1 n;
n1 <<= 1;
while( !( n1 & i ) ) i >>= 1;
return i;
}
return (n&1)?2:n;
}
return 0xFFFFFFFF;
}
NitRic Messages postés 402 Date d'inscription mardi 1 mai 2001 Statut Membre Dernière intervention 15 août 2011
9 mars 2005 à 21:02
j'vais me faire un jolie GUI avec boutons, editbox et compagnie et j'vais lancer les tests derrière tout ca ...

J'ai parlé de MFC parce que dans ton fichier resource il y avait un #include ou quelque chose du genre, et moi pas avoir ca ...


d'autres résultats:
-----------------------------------
Autre(__inline) - Matt67(!__inline)
-
Autre: 99894968
Matt67: 267824238
-
Matt67: 267612270
Autre: 99645088

------------------------------------
Autre(!__inline) - Matt67(__inline)
-
Autre: 211826517
Matt67: 106929026
-
Matt67: 107290040
Autre: 212106307

------------------------------------
Autre(!__inline) - Matt67(!__inline)
-
Autre: 212236292
Matt67: 267871849
-
Matt67: 267834713
Autre: 211729585

-------------------------------------
Autre(__inline) - Matt67(__inline)
-
Autre: 99666052
Matt67: 107482668
-
Matt67: 107109181
Autre: 99901842

--------------------------------------

Le tout avec le même code(test) qui ce trouve plus haut.

Au fait, je sais comment créer un projet, le configurer, compiler, etc ... et je me répète mais, j'utilise VS6.

Je me demande encore pourquoi sur ton poste, ma fonction est plus lente que la tienne ...

Je n'ai pas inclus le test de la fonction ASM car elle arrive toujours derrière alors c'est inutile ...



~(.:: NitRic ::.)~
cs_Matt67 Messages postés 549 Date d'inscription samedi 6 septembre 2003 Statut Membre Dernière intervention 6 mars 2010 3
9 mars 2005 à 20:22
Bonsoir,

Pas de MFC dans mon projet, que du WIN32.
Tu compiles avec quoi ?
VC++ (6) tu ouvres le projet et tu compiles et normalement pas de probleme (je me repete, pas de MFC).

DEV C++, nouveau projet et tu ajoutes les differents fichiers (un .cpp, un .h et un .rc) et hop ca roule.

Je ne vois pas en quoi les dialogs viennent perturber le resultat ???
As tu regardé le code car le fait d'appuyer sur l'un ou l'autre bouton ne change rien sinon qu'on appelle une fonction differentes !!!

Matt...
NitRic Messages postés 402 Date d'inscription mardi 1 mai 2001 Statut Membre Dernière intervention 15 août 2011
9 mars 2005 à 20:10
J'ai du retirer ton dialog étant donné que je n'utilise pas les MFC's et ne les est pas installés. Mais je n'ai pas touché au reste de ton code que voici:

#include <windows.h>
#include

using namespace std;

#define MAXVAL 0xFFFFFF

HWND hMatt, hAutre, hasm;
char szappname[] = "PowTwo";

#define ALIGN(x,y) ( x = ((x + (y - 0x00000001u)) & ~(y - 0x00000001u)) )

__inline unsigned Autre( unsigned x )
{
register unsigned y;

if ( x < 0x80000000 && ALIGN(x, 2) )
{
y = 0x80000000;
do
{
} while ( (y >>= 1) >= x );
x = (y << 1);
}
return ( (x <= 0x80000000) ? x : 0xffffffffu );
}


unsigned Matt(unsigned d)
{
unsigned r = 0x80000000;

if(!d) return 0;
if(d > r) return 0xFFFFFFFF;
if(d == 1) return 2;

while((r >>= 1) >= d);
r <<= 1;

return r;
}

__declspec(naked) DWORD __fastcall Puiss2SupEgal_ASM(DWORD d)
{
__asm {
mov eax, ecx
cmp eax, 1
jb short ramExit
ja short nbrOK
inc eax
nbrOK:
mov edx, eax
bsr ecx, eax
mov eax, 1
shl eax, cl
cmp eax, edx
jae short ramExit
shl eax, 1
jnz short ramExit
mov eax, -1
ramExit:
ret 0
}
}

void Teste_Autre()
{
LARGE_INTEGER lideb, lifin;
DWORD i = MAXVAL, r;
char buff[20];
QueryPerformanceCounter(&lideb);
for(i=0; i<=0x80000000; i++)
r = Autre(i);
QueryPerformanceCounter(&lifin);

lifin.QuadPart -= lideb.QuadPart;
_ui64toa(lifin.QuadPart, buff, 10);
cout << "Autre: " << buff << endl;
}

void Teste_Matt()
{
LARGE_INTEGER lideb, lifin;
DWORD i = MAXVAL, r;
char buff[20];
QueryPerformanceCounter(&lideb);
for(i=0; i<=0x80000000; i++)
r = Matt(i);
QueryPerformanceCounter(&lifin);

lifin.QuadPart -= lideb.QuadPart;
_ui64toa(lifin.QuadPart, buff, 10);
cout << "Matt67: " << buff << endl;
}

void Teste_ASM()
{
LARGE_INTEGER lideb, lifin;
DWORD i = MAXVAL, r;
char buff[20];
QueryPerformanceCounter(&lideb);
for(i=0; i<0x80000000; i++)
r = Puiss2SupEgal_ASM(i);

QueryPerformanceCounter(&lifin);
lifin.QuadPart -= lideb.QuadPart;
_ui64toa(lifin.QuadPart, buff, 10);
cout << "ASM: " << buff << endl;
}

int main( int argc, char * argv[] )
{

unsigned i, a;
for ( i = 0u; i <= 0x80000000; i++ )
a = Autre(i);

cout << a << endl << endl;

Teste_Matt();
Teste_Autre();
Teste_ASM();

cout << endl;
return 0;

}

/****************************************
* Résultats:

2147483648

Autre : 112422269
Matt67 : 300881971
ASM : 327010421

Press any key to continue
*
****************************************/

Au fait, oubliez les dialogs et compagnie pour ce genre de test, un bouton pour Matt67, un autre pour ASM, etc .... Donnez une chance égale à chaque fonction. Faire ce genre de test de votre facon ne fait que fausser les résultats.



~(.:: NitRic ::.)~
cs_Matt67 Messages postés 549 Date d'inscription samedi 6 septembre 2003 Statut Membre Dernière intervention 6 mars 2010 3
9 mars 2005 à 09:15
Bonjour,

Voici le lien du projet que j'ai utilisé pour faire mes tests
(Celui de BruNews, modifié pour trois fonctions)

mirabon.free.fr/win32/Test_Expo2.zip

si tu peux essayer et me tenir au courant,

Matt...
NitRic Messages postés 402 Date d'inscription mardi 1 mai 2001 Statut Membre Dernière intervention 15 août 2011
8 mars 2005 à 22:27
C'est moi, encore et encore ...
Si tu veux celle du linker aussi:

kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /machine:I386 /out:"Release/test.exe"
NitRic Messages postés 402 Date d'inscription mardi 1 mai 2001 Statut Membre Dernière intervention 15 août 2011
8 mars 2005 à 22:20
un p'tit dernier, en parlant de `__inline`, j'ai mis sa fonctione `__inline` aussi mais, ca change pas grand chose ...

NitRic: 46.02 sec (46016 ms) - 2147483648
Matt67: 57.48 sec (57482 ms) - 2147483648




~(.:: NitRic ::.)~
NitRic Messages postés 402 Date d'inscription mardi 1 mai 2001 Statut Membre Dernière intervention 15 août 2011
8 mars 2005 à 22:13
J'ai VS6, la voilà:

/nologo /G6 /ML /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FAs /Fa"Release/" /Fo"Release/" /Fd"Release/" /FD /c

Je l'ai modifié quelques fois(sauf aujourd'hui) mais, mes résultats était les même ...


les derniers tests que j'ai fait(et ferai)
dans une boucle de 0 à 0x80000000 pour tous les tests

avec la valeur 0x80000000 seulement:
- NitRic: 45.37 sec (45365 ms) - 2147483648
- Matt67: 65.95 sec (65945 ms) - 2147483648

avec la valeur 0 seulement:
- NitRic: 49.58 sec (49581 ms) - 0
- Matt67: 29.93 sec (29933 ms) - 0

avec la valeur 5 seulement:
- NitRic: 325.51 sec (325508 ms) - 8
- Matt67: 338.00 sec (337996 ms) - 8

avec la valeur -1(>0x80000000) seulement:
- NitRic: 34.26 sec (34259 ms) - 4294967295
- Matt67: 41.16 sec (41159 ms) - 4294967295

avec la valeur 1 seulement:
- NitRic: 342.08 sec (342081 ms) - 2
- Matt67: 45.23 sec (45235 ms) - 2

avec toutes les valeurs de 0 à 0x80000000:
- NitRic: 45.43 sec (45425 ms) - 2147483648
- Matt67: 68.18 sec (68178 ms) - 2147483648


Note, pour les valeurs uniques(0, 1, 5, 0x80000000 et -1) je
n'ai pas pus mettre ma fonction `__inline` car le compilo
détectait que c'était toujours la même valeur donc
résultat: 0.00 sec (0 ms) pour ma fonction, cela n'entre
pas dans les stats évidemment ...

J'ai utilisé clock() pour ces tests, étant donné l'écart
entre les deux fonctions, clock() n'influence en rien
le temps d'exécution ...

Pourquoi avec la valeur `1` ma fonction est-elle si lente
comparée à celle de Matt67? C'est simple, ma fonction entre
dans la boucle si < 0x80000000 && > 0, donc, la boucle est
exécutée contrairement à Matt67. Cependant, comme j'ai déjà
dis, un soft ne fonctionne pas avec une seul valeur unique!
Faut prévoir! Les valeurs aléatoire sont le meilleur moyen
de tester un code/fonction si celle-ci doit évidemment recevoir
des valeurs aléatoire, comme dans le cas présent. Lorsqu'on
optimise ou code tout simplement une fonction, faut prévoir
les valeurs les plus succeptibles d'arriver et non l'inverse.
Généralement, lorsqu'on appel une fonction, on lui envoie des
valeurs valide! Alors, faut les prévoirs dès le départ.
Il ne faut pas optimiser les `bugs` et valeurs non valide
mais plutôt le contraire. Trouver le juste millieux.

Je cherche encore à comprendre comment, Matt67 arrive à
avoir un meilleur résultat que ma fonction sur son poste.
Il à retiré le keyword `__inline`? Si c'est ca alors il
ne faut pas, son point fort est justement le fait qu'elle
est `__inline`. Comme j'ai `encore` déjà dis, je ne cherche
pas à être le meilleur/avoir la meilleur fonction/etc ...
mais plutôt à comprendre comment, sur deux postes différents,
deux fonctions peuvent être de rapiditées inverse!?!?!? Je
test depuis hier, je ne fait que ca et je ne comprend pas ...
Donc si d'autre personnes peuvent tester aussi, ca pourait être
bien d'avoir une moyenne sans ce fier à deux poste et qui
donne des résultats inverse en plus ...





~(.:: NitRic ::.)~
Hylvenir Messages postés 364 Date d'inscription mercredi 11 février 2004 Statut Membre Dernière intervention 5 octobre 2006 2
8 mars 2005 à 21:39
Salut,
Tu as ta ligne de commande complète de compilation ?
NitRic Messages postés 402 Date d'inscription mardi 1 mai 2001 Statut Membre Dernière intervention 15 août 2011
8 mars 2005 à 20:46
Au fait, avec la valeur 5, ca force les deux fonctions à entrer dans la boucle, dans tous les cas.

5 > 0
5 < 0x80000000
5 != 1
boucle:
...
...
ret



~(.:: NitRic ::.)~
NitRic Messages postés 402 Date d'inscription mardi 1 mai 2001 Statut Membre Dernière intervention 15 août 2011
8 mars 2005 à 20:41
Okay BruNews, pas d'problème :}

J'ai fais un autre test, avec la valeur 5 seulement

for ( i = 0; i < 0x80000000; i++ )
a = func( 5 );

Matt67 l'emporte de peu:

NitRic: 338.14 sec (338136 ms) - 8
Matt67: 338.12 sec (338116 ms) - 8
Press any key to continue

Mais un soft ne fonctionne pas avec une seul valeur!

Bref, tout me porte à croire que ma/mes fonction(s) l'emporte sur toutes les autres. Ce que je n'arrive pas à comprendre(et vous le savez déjà), ce sont les résultats de Matt67 ...

Personne n'a de réponse à ce sujet ?




~(.:: NitRic ::.)~
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
8 mars 2005 à 19:51
ah oui excuse pour le label de JMP, j'ai encore lu trop vite et en travers. Je m'en retourne à mes occupations.
NitRic Messages postés 402 Date d'inscription mardi 1 mai 2001 Statut Membre Dernière intervention 15 août 2011
8 mars 2005 à 19:35
Non, il ne va pas dans la boucle, le label 20692, c'est lui:

$L20692:
jbe SHORT $L20690
or eax, -1 ; si > 0x80000000
$L20690:
ret 0
_puissance_2 ENDP


Cependant, j'ai fais une autre version, moin rapide que celle `__inline`, car ma nouvelle version n'est pas `__inline`, mais néanmoin plus rapide que celle de Matt67(sur mon poste en tout cas):

version assembleur de ma fonction:
NitRic: 153808384
Matt67: 283329521
Press any key to continue

la voilà:

__declspec(naked)
unsigned __fastcall pow_2( unsigned x )
{__asm{
; dans les tests que Matt67 et moi faisont,
; les jump ici ne seront exécutés que deux
; fois(test: 0-0x80000000)
cmp ecx, -2147483648
ja SHORT lbl_isover ; si >
je lbl_isequal ; si ==
inc ecx
and ecx, -2
je SHORT lbl_iszero ; si 0
mov eax, -2147483648

lbl_boucle_001:
shr eax, 1
cmp eax, ecx
jae SHORT lbl_boucle_001 ; tant que < x
add eax, eax ; <<1
ret 0

lbl_isequal: ; == 0x80000000
mov eax, ecx
ret 0
lbl_iszero: ; == 0x0
xor eax, eax
ret 0
lbl_isover: ; > 0x80000000 => return 0xffffffffu;
or eax, -1
ret 0
}}


Tous les tests que je fais, me font croire que _mes_ fonctions sont plus rapide, or, Matt67 nous donne des résultats prouvant le contraire, pourquoi? Ont fait pourant les même tests! Désolé mais je n'arrive toujours pas à comprendre et j'aimerais bien!

Dans mes tests, les jump ne sont exécutés que deux fois tout au plus or, dans la fonction de Matt67, ils seront exécutés `0x80000000-2/3` fois. Qui peut m'expliquer, s'il vous plaît?



~(.:: NitRic ::.)~
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
8 mars 2005 à 19:14
Mais si, si on jmp sur une sortie directe c'est par force meilleur.
Regarde dans la tienne:
cmp eax, -2147483648 ; 80000000H
jae SHORT $L20692
donc si >= on s'en va dans la boucle, non il faudrait à la place:
cmp eax, -2147483648 ; 80000000H
je SHORT SortieDirecte ; valeur non modifiée
ja short SortieMoinsUn
; ici on entre dans la boucle
NitRic Messages postés 402 Date d'inscription mardi 1 mai 2001 Statut Membre Dernière intervention 15 août 2011
8 mars 2005 à 17:38
d'autres tests:

sans __inline
NitRic: 204736449
Matt67: 228632458
Press any key to continue


les deux __inline
NitRic: 95553604
Matt67: 113568378
Press any key to continue


J'arrive toujours pas à comprendre par contre. Même en regardant le source ASM généré derrière, on voit tout de suite tous les `jump/ret/...` dans ta fonction, pour les valeurs 0 et > 0x80000000 il fait ~trois `jump`, or, dans la mienne, aucun, sauf si > 0x80000000. Ta fonction et la mienne ce ressemble beaucoup, en ASM, le code est identique à l'exception de tes trois `jump` au début, or, un `jump` est loin d'être ce qu'il y à de plus performant. Dans nos tests, on test des valeurs valide, 0-0x80000000 donc, dans ma fonction: 1 `jump`, dans la tienne, 1+ `jump` ... Comment des `jump` peuvent ils arriver à `accelérer` l'exécution d'une fonction !?


Le source ASM des deux fonctions(non __inline):

La mienne:
_puissance_2 PROC NEAR
mov eax, DWORD PTR _x$[esp-4] ; met x dans `eax`
cmp eax, -2147483648 ; 80000000H
jae SHORT $L20692 ; si > 0x80000000 => JUMP (une fois)
inc eax
and eax, -2 ; fffffffeH ; ALIGN(x, 2)
je SHORT $L20491 ; si 0> JUMP (une fois)
mov ecx, -2147483648 ; 80000000H ; aide pour la vitesse d'accès

$L20492: ; et la tite boucle, on est arrivé rapidement non?
shr ecx, 1
cmp ecx, eax
jae SHORT $L20492
lea eax, DWORD PTR [ecx+ecx] ; x = (y << 1)

$L20491:
cmp eax, -2147483648 ; 80000000H

$L20692:
jbe SHORT $L20690
or eax, -1 ; si > 0x80000000

$L20690:
ret 0
_puissance_2 ENDP



La tienne:
@Matt67@4 PROC NEAR
test ecx, ecx ; si pas zéro => JUMP
jne SHORT $L20469
xor eax, eax ; met à zéro et => return 0;
ret 0

$L20469:
cmp ecx, -2147483648 ; si <80000000H> JUMP
jbe SHORT $L20470
or eax, -1 ; return 0xffffffffu;
ret 0

$L20470:
cmp ecx, 1
jne SHORT $L20681 ; si !1> JUMP
mov eax, 2 ; return 2;
ret 0

$L20681: ; un premier test avant d'entrer dans la boucle
mov eax, 1073741824 ; 40000000H
cmp ecx, eax
ja SHORT $L20474

$L20473: ; et la tite boucle ici, enfin arrivé après trois JUMP
shr eax, 1
cmp eax, ecx
jae SHORT $L20473

$L20474:
add eax, eax ; r <<= 1;
ret 0
@Matt67@4 ENDP



Comme j'ai déjà dis, j'suis pas expert en ASM mais j'ai quand même quelques bases et ces quelques bases me disent que des `jump` n'accelère pas l'exécution d'une fonction ...

Je ne pas veux pas avoir la fonction la plus rapide mais simplement arriver à comprendre :/

BruNews à l'air de connaître l'ASM, il pourait peut-être donner son avis!?



~(.:: NitRic ::.)~
NitRic Messages postés 402 Date d'inscription mardi 1 mai 2001 Statut Membre Dernière intervention 15 août 2011
8 mars 2005 à 16:41
Comment fais-tu pour arriver à ce résultat? Moi j'obtient ceci:

NitRic: 44.24 sec (44243 ms) - 2147483648
Matt67: 78.13 sec (78132 ms) - 2147483648

Presque le double!?!?!?!?

C'est bien ta fonction ca?:

unsigned __fastcall Matt67(unsigned d)
{
unsigned r = 0x80000000;
if(!d) return 0;
if(d > r) return 0xFFFFFFFF;
if(d == 1) return 2;
while((r >>= 1) >= d);
r <<= 1;
return r;
}


TEST:

s = clock();
for ( i =0; i < 0x80000000; i++ )
a = puissance_2( i );
e = clock();
printf("NitRic: %4.2f sec (%u ms) - %u\n", (e-s)/(double)CLOCKS_PER_SEC, (e-s), a);

s = clock();
for ( i =0; i < 0x80000000; i++ )
a = Matt67( i );
e = clock();
printf("Matt67: %4.2f sec (%u ms) - %u\n", (e-s)/(double)CLOCKS_PER_SEC, (e-s), a);


Avec le QueryPerformanceCounter() j'obtient ceci:

NitRic: 109646232
Matt67: 281617198
Press any key to continue

LARGE_INTEGER begin, end;

/*s = clock();*/
QueryPerformanceCounter(&begin);
for ( i =0; i < 0x80000000; i++ )
a = puissance_2( i );
QueryPerformanceCounter(&end);
printf("NitRic: %u\n", (end.QuadPart - begin.QuadPart));
/*e = clock();
printf("NitRic: %4.2f sec (%u ms) - %u\n", (e-s)/(double)CLOCKS_PER_SEC, (e-s), a);*/

/*s = clock();*/
QueryPerformanceCounter(&begin);
for ( i =0; i < 0x80000000; i++ )
a = Matt67( i );
QueryPerformanceCounter(&end);
printf("Matt67: %u\n", (end.QuadPart - begin.QuadPart));
/*e = clock();
printf("Matt67: %4.2f sec (%u ms) - %u\n", (e-s)/(double)CLOCKS_PER_SEC, (e-s), a);*/

return 0;


la version de ma fonction avec laquelle j'ai testé:
__inline
unsigned puissance_2( unsigned x )
{

register unsigned y;

if ( x < 0x80000000 && ALIGN(x, 2) )
{

y = 0x80000000;
do
{
} while ( (y >>= 1) >= x );
x = (y << 1);

}

return ( (x <= 0x80000000) ? x : 0xffffffffu );

}


J'aimerais bien comprendre ...


~(.:: NitRic ::.)~
cs_Matt67 Messages postés 549 Date d'inscription samedi 6 septembre 2003 Statut Membre Dernière intervention 6 mars 2010 3
8 mars 2005 à 09:02
Bonsoir,

j'ai fait quelques tests sur un interval de 0 à 0x80000000

QueryPerformanceCounter(&lideb);
for(i=0; i<0x80000000; i++)
r = Puiss2SupEgal_C(i);
QueryPerformanceCounter(&lifin);

resultat (3 tests par fonctions)
NitRic
85356885810
85092196462
85845629587

Matt67
70374001567
70883189797
70309812128

donc c'est pas encore gagné pour toi NitRic,

Matt...
NitRic Messages postés 402 Date d'inscription mardi 1 mai 2001 Statut Membre Dernière intervention 15 août 2011
7 mars 2005 à 22:29
Hey! Encore moi. Cette fois c'est la bonne:

#define ALIGN(x,y) ( x = ((x + (y - 0x00000001u)) & ~(y - 0x00000001u)) )

__inline
unsigned puissance_2( unsigned x )
{

register unsigned y;

if ( x < 0x80000000 && ALIGN(x, 2) )
{

y = 0x80000000;
do
{
} while ( (y >>= 1) >= x );
x = (y << 1);

}

return ( (x <= 0x80000000) ? x : 0xffffffffu );

}

Voilà, j'essais encore de trouver une méthode sans boucle mais c'est pas simple et j'commence à croire que c'est impossible d'avoir quelque chose de rapide/efficace/safe/... sans boucle mais bref, voilà, j'ai regardé vos exemples et j'ai fais une version `optimisée`:

NitRic: 80.59 sec (80595 ms) - 0
BruNews_C: 117.68 sec (117680 ms) - 0
Matt67: 108.11 sec (108105 ms) - 0
Hylvenir: 137.15 sec (137147 ms) - 0

J'ai perdu ~25sec avec la boucle mais bon, mieux vaut quelque chose de fonctionnel et ~rapide, que quelque chose de ~fonctionnel et rapide!

Ma fonction, pour la valeur 0, retourne 0, pour une valeur suppérieure à 0x80000000 retourne 0xffffffff

Donc, possibilitées: 0-0x80000000 ou 0xffffffff




~(.:: NitRic ::.)~
NitRic Messages postés 402 Date d'inscription mardi 1 mai 2001 Statut Membre Dernière intervention 15 août 2011
7 mars 2005 à 20:33
Je sais pas si tu le savais Hylvenir mais, tu as raison ...

J'avais fait une comparaison avec celle de Matt67 mais, j'ai du me tromper et appeler deux fois _ma_ fonction ...

J'vais retourner penser ...



~(.:: NitRic ::.)~
Hylvenir Messages postés 364 Date d'inscription mercredi 11 février 2004 Statut Membre Dernière intervention 5 octobre 2006 2
7 mars 2005 à 18:07
12, 20, 24 ? étrange puissance de 2 s'il en est ;)
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
7 mars 2005 à 18:06
pressé de tester ce code ce qui sera fait dans la soirée
NitRic Messages postés 402 Date d'inscription mardi 1 mai 2001 Statut Membre Dernière intervention 15 août 2011
7 mars 2005 à 17:59
Voilà, code corrigé:

__inline
unsigned puissance_2( unsigned x ) {
if ( x < (unsigned)-1 )
{
x = (( (x + 0x00000001u) & ~(0x00000001u) ) * 2 );
}
return x;
}

on arrondit(prochain multiple >= 2) et ensuite *2

for ( i = 0u; i < 513; i++ )
printf("%u, ", puissance_2( i ));

résultat:

0, 4, 4, 8, 8, 12, 12, 16, 16, 20, 20, 24, 24, 28, 28, 32, 32, 36, 36, 40, 40, 4
4, 44, 48, 48, 52, 52, 56, 56, 60, 60, 64, 64, 68, 68, 72, 72, 76, 76, 80, 80, 8
4, 84, 88, 88, 92, 92, 96, 96, 100, 100, 104, 104, 108, 108, 112, 112, 116, 116,
120, 120, 124, 124, 128, 128, 132, 132, 136, 136, 140, 140, 144, 144, 148, 148,
152, 152, 156, 156, 160, 160, 164, 164, 168, 168, 172, 172, 176, 176, 180, 180,
184, 184, 188, 188, 192, 192, 196, 196, 200, 200, 204, 204, 208, 208, 212, 212,
216, 216, 220, 220, 224, 224, 228, 228, 232, 232, 236, 236, 240, 240, 244, 244,
248, 248, 252, 252, 256, 256, 260, 260, 264, 264, 268, 268, 272, 272, 276, 276,
280, 280, 284, 284, 288, 288, 292, 292, 296, 296, 300, 300, 304, 304, 308, 308,
312, 312, 316, 316, 320, 320, 324, 324, 328, 328, 332, 332, 336, 336, 340, 340,
344, 344, 348, 348, 352, 352, 356, 356, 360, 360, 364, 364, 368, 368, 372, 372,
376, 376, 380, 380, 384, 384, 388, 388, 392, 392, 396, 396, 400, 400, 404, 404,
408, 408, 412, 412, 416, 416, 420, 420, 424, 424, 428, 428, 432, 432, 436, 436,
440, 440, 444, 444, 448, 448, 452, 452, 456, 456, 460, 460, 464, 464, 468, 468,
472, 472, 476, 476, 480, 480, 484, 484, 488, 488, 492, 492, 496, 496, 500, 500,
504, 504, 508, 508, 512, 512, 516, 516, 520, 520, 524, 524, 528, 528, 532, 532,
536, 536, 540, 540, 544, 544, 548, 548, 552, 552, 556, 556, 560, 560, 564, 564,
568, 568, 572, 572, 576, 576, 580, 580, 584, 584, 588, 588, 592, 592, 596, 596,
600, 600, 604, 604, 608, 608, 612, 612, 616, 616, 620, 620, 624, 624, 628, 628,
632, 632, 636, 636, 640, 640, 644, 644, 648, 648, 652, 652, 656, 656, 660, 660,
664, 664, 668, 668, 672, 672, 676, 676, 680, 680, 684, 684, 688, 688, 692, 692,
696, 696, 700, 700, 704, 704, 708, 708, 712, 712, 716, 716, 720, 720, 724, 724,
728, 728, 732, 732, 736, 736, 740, 740, 744, 744, 748, 748, 752, 752, 756, 756,
760, 760, 764, 764, 768, 768, 772, 772, 776, 776, 780, 780, 784, 784, 788, 788,
792, 792, 796, 796, 800, 800, 804, 804, 808, 808, 812, 812, 816, 816, 820, 820,
824, 824, 828, 828, 832, 832, 836, 836, 840, 840, 844, 844, 848, 848, 852, 852,
856, 856, 860, 860, 864, 864, 868, 868, 872, 872, 876, 876, 880, 880, 884, 884,
888, 888, 892, 892, 896, 896, 900, 900, 904, 904, 908, 908, 912, 912, 916, 916,
920, 920, 924, 924, 928, 928, 932, 932, 936, 936, 940, 940, 944, 944, 948, 948,
952, 952, 956, 956, 960, 960, 964, 964, 968, 968, 972, 972, 976, 976, 980, 980,
984, 984, 988, 988, 992, 992, 996, 996, 1000, 1000, 1004, 1004, 1008, 1008, 101
2, 1012, 1016, 1016, 1020, 1020, 1024, 1024, Press any key to continue

pour ce qui est du temps d'exécution, il n'y à que ~5sec en plus, il reste le plus rapide, !?!?YOUPI!?!?



~(.:: NitRic ::.)~
NitRic Messages postés 402 Date d'inscription mardi 1 mai 2001 Statut Membre Dernière intervention 15 août 2011
7 mars 2005 à 17:46
Non, c'est moi qui n'est pas bien compris le `cahier des charges` je crois. Ma fonction renvoie les nombres paires, c'est à dire: 0, 2, 4, 6, 8, 10, 12, ... Il arrondit si on veut. Le prochain multiple >= 2. On dirait que mon cerveau à traduit `puissance` par `multiple` :} bref, j'vais corriger ma fonction et la reposter à nouveau.

Pour le `__inline`, moi j'en ai besoin, j'aime pas le laisser mettre ce qu'il veut `inline`. Pour ce qui est de ta stackframe, ici, VS6 n'en met pas, ton code est clean mais c'est vrai qu'en macro ca pourait être bien, un call en moin :}



~(.:: NitRic ::.)~
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
7 mars 2005 à 08:56
Salut NitRic,

pour ASM bonne remarque, il faut bien sur inverser la 2eme et 3eme ligne.

Ai-je mal transcrit ton code ??? pour 513 en entrée, il me sort 514 au lieu de 1024.

A propos du inline, même pas la peine de l'indiquer explicitement, dès le début j'avais vu que le compilo insère le C direct en inline sans rien lui demander (faut bien sur compiler avec les optimisations mais allait sans dire). Pour avoir des comparaison vraiment valables, faudrait donc que je réécrive ASM en format macro sinon dans l'état actuel il me met une stackframe à tout coup (bourrique de compilo..). Je corrigerai tout cela dès que je ne serai plus aux 35h de repos par semaine...
NitRic Messages postés 402 Date d'inscription mardi 1 mai 2001 Statut Membre Dernière intervention 15 août 2011
7 mars 2005 à 04:50
au fait BruNews, à ton premier jump(ja) dans ta fonction en ASM, j'crois que tu as oublié `eax`, c'est possible?

__asm {
cmp ecx, 80000000h
ja puissExit
; ...
mov eax, -1
puissExit:
ret 0
}

un label en plus ou un ajout au début devrait aider mais bon, j'suis pas expert en ASM alors j'dis peut-être n'importe quoi :}



~(.:: NitRic ::.)~
NitRic Messages postés 402 Date d'inscription mardi 1 mai 2001 Statut Membre Dernière intervention 15 août 2011
7 mars 2005 à 04:29
Autre correction:

__inline static
unsigned puissance_2( unsigned x )
{
if ( x < (unsigned)-1 )
{
x = ( (x + 0x00000001u) & ~(0x00000001u) );
}
return x;
}

j'ai testé les différents algos présenté ici(version final)

je n'ai qu'un petit K7 550(génération P3) alors les résultat sont un peu plus élevés que les votre mais au final, ca revient au même

NitRic: 38.18 sec (38184 ms) - 0
BruNews_ASM: 138.16 sec (138159 ms) - 2
BruNews_C: 138.46 sec (138459 ms) - 0
Matt67: 125.98 sec (125981 ms) - 0
Hylvenir: 139.06 sec (139060 ms) - 0
Press any key to continue

le chiffre à la fin de chaque ligne c'est la valeur retourné de chaque fonction pour la valeur 0



au fait, si j'suis complètement dans l'champ avec mes affaires, faut me le dire hein!

voilà mon code:

/* main.c */
#include <stdio.h>
#include <time.h>


__declspec(naked) unsigned BruNews_ASM(unsigned d)
{
__asm {
cmp ecx, 80000000h
ja short puissExit
mov eax, ecx
cmp eax, 1
jb short puissExit
ja short nbrOK
inc eax
nbrOK:
mov edx, eax
bsr ecx, eax
mov eax, 1
shl eax, cl
cmp eax, edx
jae short puissExit
shl eax, 1
jnz short puissExit
;moinsUn: ; << warning C4102: 'moinsUn' : unreferenced label
mov eax, -1
puissExit:
ret 0
}
}

unsigned __fastcall BruNews_C(unsigned d)
{
unsigned r, n;
if(!d) return 0;
if(d > 0x80000000) return 0xFFFFFFFF;
if(d & 1) d++;
r = 0x80000000;
n = d;
if(d & 0x80000000) goto verifInf;
do {
r >>= 1;
d <<= 1;
} while(!(d & 0x80000000));
verifInf:
if(r < n) r <<= 1;
if(!r) r = 0xFFFFFFFF;
return r;
}

unsigned __fastcall Matt67(unsigned d)
{
unsigned r = 0x80000000;
if(!d) return 0;
if(d > r) return 0xFFFFFFFF;
if(d == 1) return 2;
while((r >>= 1) >= d);
r <<= 1;
return r;
}

unsigned Hylvenir(unsigned n)
{
unsigned i, n1;
if ( n > 0x80000000 ) return 0xFFFFFFFF;
if ( n & ( n - 1 ) )
{
i 0x80000000, n1 n;
n1 <<= 1;
while( !( n1 & i ) ) i >>= 1;
return i;
}
return (n&1)?2:n;
}

__inline static
unsigned puissance_2( unsigned x )
{
if ( x < (unsigned)-1 )
{
x = ( (x + 0x00000001u) & ~(0x00000001u) );
}
return x;
}

int main( int argc, char * argv[] )
{

unsigned i, a;
clock_t s, e;

i = (unsigned)-1;
a = 0u;

s = clock();
do {
a = puissance_2( i );
}while ( i-- );
e = clock();

printf("NitRic: %4.2f sec (%u ms) - %u\n", (e-s)/(double)CLOCKS_PER_SEC, (e-s), a);

i = (unsigned)-1;
a = 0u;

s = clock();
do {
a = BruNews_ASM( i );
}while ( i-- );
e = clock();

printf("BruNews_ASM: %4.2f sec (%u ms) - %u\n", (e-s)/(double)CLOCKS_PER_SEC, (e-s), a);

i = (unsigned)-1;
a = 0u;

s = clock();
do {
a = BruNews_C( i );
}while ( i-- );
e = clock();

printf("BruNews_C: %4.2f sec (%u ms) - %u\n", (e-s)/(double)CLOCKS_PER_SEC, (e-s), a);

i = (unsigned)-1;
a = 0u;

s = clock();
do {
a = Matt67( i );
}while ( i-- );
e = clock();

printf("Matt67: %4.2f sec (%u ms) - %u\n", (e-s)/(double)CLOCKS_PER_SEC, (e-s), a);

i = (unsigned)-1;
a = 0u;

s = clock();
do {
a = Hylvenir( i );
}while ( i-- );
e = clock();

printf("Hylvenir: %4.2f sec (%u ms) - %u\n", (e-s)/(double)CLOCKS_PER_SEC, (e-s), a);

return 0;

}


Je n'ai modifié que le nom des types, changé les U32/DWORD pour un unsigned

j'aurais peut-être utilisé votre QueryPerformanceCounter() mais vue les résultats, clock() suffisait amplement je crois ...

voilà, c'est tout


~(.:: NitRic ::.)~
NitRic Messages postés 402 Date d'inscription mardi 1 mai 2001 Statut Membre Dernière intervention 15 août 2011
7 mars 2005 à 03:10
Correction:

__inline
unsigned puissance_2( unsigned x ) {
if ( x < (unsigned)-1 ) {
return ( (x + 0x00000001u) & ~(0x00000001u) );
}
return (unsigned)-1;
}




~(.:: NitRic ::.)~
NitRic Messages postés 402 Date d'inscription mardi 1 mai 2001 Statut Membre Dernière intervention 15 août 2011
7 mars 2005 à 03:00
C'est bon ca? Ca respect le cahier des charges?


#include <stdio.h>

#ifdef __cplusplus
extern "C" {
#endif

/* ca pourait très bien être une macro aussi:

#define PUISSANCE_2(x) ((x+0x00000001u) & ~(0x00000001u))

unsigned i = PUISSANCE_2(21);

*/
__inline
unsigned puissance_2( unsigned x ) {
if ( x < (((unsigned)-1)-1) )
return ( (x + 0x00000001u) & ~(0x00000001u) );
return (unsigned)-1;
}

#ifdef __cplusplus
}
#endif

int main()
{

unsigned i;

for ( i = 0u; i < ((unsigned)-1); i++ )
printf("%u, ", puissance_2( i ));

return 0;

}


désolé s'il y à des fautes de frappe, j'ai fait ca online



~(.:: NitRic ::.)~
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
3 mars 2005 à 17:16
Seul compte que l'algo soit le plus performant possible.
Mis bon, rien que le temps de chargement en fpu (fild) puis dans l'autre sens (fistp), je n'ai même pas eu envie d'essayer. Ceci dit faudrait tester.
cs_JCDjcd Messages postés 1138 Date d'inscription mardi 10 juin 2003 Statut Membre Dernière intervention 25 janvier 2009 4
3 mars 2005 à 16:44
on a les droit d'utiliser des doubles ?
garslouche Messages postés 583 Date d'inscription mardi 26 novembre 2002 Statut Membre Dernière intervention 29 mai 2015 1
3 mars 2005 à 13:41
Je ne suis pas spécialiste des optimisations mais avez-vous essayé avec la fonction log ?

pow( 2, (int) ( log(param) / log(2) ) + 1 )

(bien sur pow n'est pas la fonction adaptée - puisque c'est pour les double - mais c'est l'idée...)
Hylvenir Messages postés 364 Date d'inscription mercredi 11 février 2004 Statut Membre Dernière intervention 5 octobre 2006 2
3 mars 2005 à 11:50
Tout à fait d'accord,
dans les tests, je fais aussi des boucles sur les valeurs extrèmes et médianes.
( valeurs entre 0 + 500, entre 0xFFFF et 0xFFFF + 500,
et 0xFFFFFFF et 0xFFFFFFF + 500 )
mais je ne les ais pas postés.
Ca permet de voir tout de suite la puissance de l'ASM dans ce cas.
cs_JCDjcd Messages postés 1138 Date d'inscription mardi 10 juin 2003 Statut Membre Dernière intervention 25 janvier 2009 4
3 mars 2005 à 11:21
"s'il lit des données au hasard", justement tout est la dedans, si on teste le temps mis pour une boucle de 0 a 4milliards, alors le programme repondera -1 dans la moitie des cas, donc un teste au debut du programme et c'est fini, par contre si on s'amuse a comparer combien de temps mettent les algo. pour repondre au nombre 5, alors surement les performance seront differentes, car il faut faire 30 fois la boucle (5 fois la boucle dans ma version), donc les perfs. vont diminuer.
Hylvenir Messages postés 364 Date d'inscription mercredi 11 février 2004 Statut Membre Dernière intervention 5 octobre 2006 2
3 mars 2005 à 08:35
1h??? tu dors jamais ? ;)
En fait, ça dépend de beauoup de chose en effet.

je n'ai utilisé que ton premier jeu de test (cas n°1).
C'est en gros le temps moyen que peut attendre l'utilisateur s'il lit des données au hasard. Un simple chronometrage pour tester le temps à la faire.

J'ai remis une version (ASM compris)
http://hylvenir.free.fr/data/puissance.cpp

Je serai intrigué de savoir si vous trouvez des résultats différents avec une compilation cl /O2 par exemple.
Bonne journée de boulot ;)
cs_JCDjcd Messages postés 1138 Date d'inscription mardi 10 juin 2003 Statut Membre Dernière intervention 25 janvier 2009 4
3 mars 2005 à 01:00
En fait tout depend de la facon de tester et du choix de la taille des nombres.
Hylvenir Messages postés 364 Date d'inscription mercredi 11 février 2004 Statut Membre Dernière intervention 5 octobre 2006 2
3 mars 2005 à 00:25
Brunews, ok merci c'est marche maintenant.

Avec un 'faux' cl voici mes derniers résultat
MIN 0, MAX 4294967294
C1 : 63sec 40ms (Brunews C )
C2 : 36sec 884ms (Brunews ASM)
C3 : 41sec 980ms (Hylvenir)
C4 : 47sec 218ms (Matt)
Hylvenir Messages postés 364 Date d'inscription mercredi 11 février 2004 Statut Membre Dernière intervention 5 octobre 2006 2
2 mars 2005 à 23:39
Brunews, ok pour l'ASM, je vais essayer avec __declspec(naked) . je vais voir si la beta 2005 accepte les optimisations (faut que je réinstalle).

Voici ma dernière version, je ne peux la tester sur cl pour le moment mais elle est pas trop mal.
( en testant le temps mis sur un cycle complet des 4 milliards, j'essaye selon tes randoms JCDjcd )

U32 Puiss2SupEgal_C3(U32 n)
{
if ( n > 0x80000000 ) return 0xFFFFFFFF;
if ( n & ( n - 1 ) )
{
U32 i 0x80000000, n1 n;
n1 <<= 1;
while( !( n1 & i ) ) i >>= 1;
return i;
}
return (n&1)?2:n;
}

En tout cas c'était rigolo j'ai appris pas mal sur ce simple exercice.
cs_JCDjcd Messages postés 1138 Date d'inscription mardi 10 juin 2003 Statut Membre Dernière intervention 25 janvier 2009 4
2 mars 2005 à 23:11
il existe deux manieres differentes de tester les performances, soit les nombres de departs sont uniformes, soit le resultat est uniforme
1er methode : Pow2(Random(0,0x80000000))
2nd methode : Pow2(1<<(Random(0,31)))

les performances changerons.
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
2 mars 2005 à 23:09
Pour compiler l'ASM, faut que soit absolument certain que le compilo ne t'insère pas une stackframe sinon bien sur c'est foutu d'avance pour les perfs, pour cela que __declspec(naked) sur VC++ et ainsi compilo n'y touche pas du tout, avec gcc je ne sais pas comment tu peux faire.
J'ai refait des tests et y a pas photo, Matt67 l'emporte haut la main.
cs_Urgo Messages postés 780 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 16 avril 2009 1
2 mars 2005 à 22:44
D'accord avec Matt67... Bien joué ;)
Hylvenir Messages postés 364 Date d'inscription mercredi 11 février 2004 Statut Membre Dernière intervention 5 octobre 2006 2
2 mars 2005 à 22:36
Bonsoir, alors après quelques tests mon point suit.
Mais d'abord, je n'arrive pas à valider la fonction ASM original
(mes résultats sont faux), mais elle peut être plus lente que le C de Matt (cf plus bas).
Au niveau des perfs, faudrait se mettre d'accord sur 'performance' (sûrement en moyenne).
Pour faire le test de perf, j'ai utilisé une boucle sur toutes les valeurs possibles. ( 0 à 4 milliards environ ).
Ce qu'on peut voir, c'est que la moitié des valeurs son invalides ( n > 0x80000000 ), donc une bonne solution serait de tester rapidement ce cas et sortir ( comme Matt ), ensuite les valeurs valides ont plus souvent des bits élevés. ( 0x8FFF0000 ce mask doit représenter 80% des valeurs valides).
En conclusion pour faire un truc rapide :
1. traiter un priorité les 50% des valeurs en erreur.
(n > 0x80000000 par exemple)
2. traiter les bits de poids fort en priorité.
(le plus rapidement possible comme Matt )

Voici le source utilisé ( mode console avec vérification si argc > 1 ) compilé avec gcc (cl j'ai pas les optimisations)

http://hylvenir.free.fr/data/puissance.cpp

Voici les temps que j'obtiens
C1 : 39sec 46ms ( Version Brunews )
C2 : 71sec 293ms ( Version JCDjcd )
C3 : 27sec 950ms ( version Hylvenir)
C4 : 26sec 828ms ( Version Matt )

Pour info la version ASM tourne moins vite que la version C de brunews. La version de Matt et la mienne tourne environ aussi vite selon.

Pour l'ASM, je ne sais pas si c'est normal que ça ne fonctionne pas. Pour le tester vous même il suffit de copier/coller le code asm dans une des fonctionc C1..4
et lancer l'exe avec un argument quelconque.
Brunews une idée ? est-ce le résultat peut dépendre de la manière de compiler ?
A t-on des précisions sur la nature des valeurs en entrée ?
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
2 mars 2005 à 22:29
Je confirme, algo de Matt67 est le meilleur tous, 30% sur asm y compris.
cs_Matt67 Messages postés 549 Date d'inscription samedi 6 septembre 2003 Statut Membre Dernière intervention 6 mars 2010 3
2 mars 2005 à 21:02
Bonsoir,

j'ai fait quelques tests sur un interval de 0 à 0x80000000

QueryPerformanceCounter(&lideb);
for(i=0; i<0x80000000; i++)
r = Puiss2SupEgal_C(i);
QueryPerformanceCounter(&lifin);

resultat (3 tests par fonctions) :
Fonction de Hylvenir :
101.364.469.072
101.339.293.005
101.459.063.767

Fonction de Matt corrigé par Urgo :
70.031.666.940
70.005.492.802
70.004.897.692

Fonction ASM :
42.974.330.512
42.914.916.886
43.126.926.097

Et vous ?

Matt...
cs_JCDjcd Messages postés 1138 Date d'inscription mardi 10 juin 2003 Statut Membre Dernière intervention 25 janvier 2009 4
2 mars 2005 à 20:05
MaxPow2_v1 00000000 : 0
MaxPow2_v1 00000001 : 0
MaxPow2_v1 00000002 : 1
MaxPow2_v1 000003E8 : 9
MaxPow2_v1 FFFFFFF6 : -1
MaxPow2_v1 80000000 : -1
MaxPow2_v1 7FFFFFFF : 30

MaxPow2_v2 00000000 : 0
MaxPow2_v2 00000001 : 0
MaxPow2_v2 00000002 : 1
MaxPow2_v2 000003E8 : 9
MaxPow2_v2 FFFFFFF6 : -1
MaxPow2_v2 80000000 : -1
MaxPow2_v2 7FFFFFFF : 30
cs_Urgo Messages postés 780 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 16 avril 2009 1
2 mars 2005 à 17:47
Code de JCDjcd ne respecte pas du tout le cahier des charges effectivement...

D'après mes tests, Hylvenir est pour l'instant le premier avec son ALGO, il dépasse même la version ASM de BruNews (chez vous aussi?)... Enfin... je ne suis pas certain que mes tests soient exacts, donc pas taper svp! :)
cs_Matt67 Messages postés 549 Date d'inscription samedi 6 septembre 2003 Statut Membre Dernière intervention 6 mars 2010 3
2 mars 2005 à 17:08
Merci Urgo, je rentre du boulot et j'allais la poster (exactement la même !!!).

Par contre avez vous regardé le code de JCDjcd, il me semble qu'il y avait un petit problème dans le retour de sa fonction ?
(Il me semble qu'il renvoyait l'exposant à 2)

Matt...
cs_Urgo Messages postés 780 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 16 avril 2009 1
2 mars 2005 à 15:57
// Version de Matt67 corrigée
DWORD __fastcall MyPuiss2SupEgal_C(DWORD d)
{
DWORD r = 0x80000000;
if(!d) return 0;
if(d > r) return 0xFFFFFFFF;
if(d == 1) return 2;
while((r >>= 1) >= d);
r <<= 1;
return r;
}
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
2 mars 2005 à 15:04
oh oui me semble bien rien qu'en regardant le code que tu as tout a fait raison.
Je vais mettre le est > 0x80000000 en entree et maj du zip.
cs_Urgo Messages postés 780 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 16 avril 2009 1
2 mars 2005 à 14:52
BruNews, lorsque je rentre 4294967295 (0xFFFFFFFF), ton algo (en C) "plante"... et me retourne rien!
Alors qu'avec l'ago en ASM, aucun problème...!

Normal ou pas?

Bye
Urgo
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
2 mars 2005 à 00:09
Hylvenir pas mal du tout, très voisin des 2 autres pour les perfs.

Urgo > ok compris cette fois, faudrait vérifier mais comme je fais cela en bossant (pas trop ce jour mais tout de même un peu) j'ai pas le temps de tout analyser.
Hylvenir Messages postés 364 Date d'inscription mercredi 11 février 2004 Statut Membre Dernière intervention 5 octobre 2006 2
1 mars 2005 à 23:55
Ma dernière version liftée ;) et c'est l'heure du dodo.
Je ne vois plus comment améliorer sans changer l'algo de toute façon.
(tests : ASM 740000, C : 1280000, ASM vainqueur ;) )

DWORD __fastcall Puiss2SupEgal_C(DWORD d)
{
DWORD i, n1 d, d1 d - 1;
if ( !d ) return 0;
if ( !( d & d1 ) ) return (d&1)?2:d;
if ( d > 0x80000000 ) return 0xFFFFFFFF;
if ( d < 0x00008000 ) i = ( d < 0x00000080 )?0x00000080:0x00008000;
else i = ( d < 0x00800000 )?0x00800000:0x80000000;

n1 <<= 1;
while( !( n1 & i ) ) i >>= 1;
return i;
}
Hylvenir Messages postés 364 Date d'inscription mercredi 11 février 2004 Statut Membre Dernière intervention 5 octobre 2006 2
1 mars 2005 à 23:49
Au fait,
bravo BruNews pour l'animation.
Ca manque quand y'a rien à la télé ;)
Hylvenir Messages postés 364 Date d'inscription mercredi 11 février 2004 Statut Membre Dernière intervention 5 octobre 2006 2
1 mars 2005 à 23:43
mes essais... avec normalement toutes les spéc respectées (j'ai que la version Initation de 2003 donc je suis pas sûr des params d'optimisations - même si j'ai l'impression que seul l'interface est bloquée pas la compilo lui-même donc le projet garde ces paramètres).


DWORD __fastcall Puiss2SupEgal_C(DWORD n)
{
DWORD i, n1 = n;
if ( !n ) return 0;
if ( !( n & n-1 ) ) return (n&1)?2:n;
if ( n > 0x80000000 ) return 0xFFFFFFFF;
if ( n < 0x00008000 ) i = ( n < 0x00000080 )?0x00000080:0x00008000;
else i = ( n < 0x00800000 )?0x00800000:0x80000000;

n1 <<= 1;
while( !( n1 & i ) ) i >>= 1;
return i;
}
cs_Urgo Messages postés 780 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 16 avril 2009 1
1 mars 2005 à 23:33
Bon, je répète plus clairement :

La fonction de Matt67 ne respecte PAS le cahier des charges (la plus proche puissance de 2 >= au param); car LUI fait : la plus proche puissance de 2 > au param!

Bon, si c'est pas clair tanpis, je vais me coucher, j'ai besoin de repos...

Bye
Urgo
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
1 mars 2005 à 23:06
Urgo > rien compris. Y a un cahier des charges, suffit de le respecter.
cs_Urgo Messages postés 780 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 16 avril 2009 1
1 mars 2005 à 22:50
BruNews, n'as tu pas oublier de traiter "2 puissance 0" (si je rentre 1, il me retourne 2!)???

Matt67, ta fonction devrait s'appeler "...Puiss2Sup_C..." (sans le Egal)

Je ferai d'autres tests demain...
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
1 mars 2005 à 22:48
Manque la verif pour retourner (DWORD) -1 en sortie dans celui de JCDjcd, il me l'avait passé sur le forum par la suite.

Même vitesse que JCDjcd, bravo Matt67 !!!
cs_Matt67 Messages postés 549 Date d'inscription samedi 6 septembre 2003 Statut Membre Dernière intervention 6 mars 2010 3
1 mars 2005 à 21:32
Bonsoir,

Dans le genre court et avec d'assez bonnes perfs :

unsigned Puiss2SupEgal_C(unsigned d)
{
unsigned Depart = 0x80000000;

while(((Depart >>= 1) > d));
Depart <<= 1;

if(d > 0x80000000) return 0xFFFFFFFF;

return Depart;
}

Par contre à voir la validité de l'algo de JCDjcd, semble pas correspondre aux "cahiers des charges"

Matt.
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
1 mars 2005 à 12:34
Proposé par JCDjcd:

typedef unsigned __int32 U32;
typedef unsigned __int64 U64;
#define B31 0x80000000
#define B63 0x8000000000000000u

typedef U32 TYPE;
#define N 32
/* si on veut tester en 64 bits
typedef U64 TYPE;
#define N 64
*/

DWORD __fastcall Puiss2SupEgal_C(TYPE n)
{
int i = 0;
int di = N>>1;
do {
if(n >= (((TYPE)1) << (i+di))) i += di;
} while((di >>= 1) > 0);
return i;
}

Pas vérifié la validité de la fonction avec le cahier des charges mais est nettement + rapide que l'originale, à peine un peu + de 2 fois celle ASM, vraiment bien.
Rejoignez-nous