Bonjour,
Différentes lectures m'avaient fait admettre que le reste d'un entier
modulo 2 ie (x % 2) produisait un code équivalent à sa version bit à bit
ie (x & 1).
int est_pair1(int n)
{
return !(n % 2);
}
Bonjour,
Différentes lectures m'avaient fait admettre que le reste d'un entier
modulo 2 ie (x % 2) produisait un code équivalent à sa version bit à bit
ie (x & 1).
int est_pair1(int n)
{
return !(n % 2);
}
Bonjour,
Différentes lectures m'avaient fait admettre que le reste d'un entier
modulo 2 ie (x % 2) produisait un code équivalent à sa version bit à bit
ie (x & 1).
int est_pair1(int n)
{
return !(n % 2);
}
Vous ne chronométrez pas les instructions que vous voulez tester, ou
disons que vous les chronométrez noyées dans le bruit. Votre programme
passe tout son temps dans les appels de fonctions, dans une moindre
mesure dans les printf(), et quelsues autres trucs.
- dans vos fonctions est_pairx(), mettre juste
return 0;
Si ça se trouve ce sera plus long ;-)
- virer le printf() dans test().
- remplacer le f(i * j) dans test() par l'une ou l'autre de vos
instructions.
- Alternativement, écrire une:
static int est_pair(int n) // ou static inline etc.
{
return !(n % 2);
}
et l'appeler directement dans test().
Puisque vous êtes sur l'optimisation, voyez le f(i*j) en fond de boucle.
Ça peut être coûteux et bien plus long (le bruit le bruit) que votre
instruction à tester, si le compilateur ne constate pas à votre place
que cette multiplication de deux valeurs non constantes n'est en fait
qu'un incrément.
Vous ne chronométrez pas les instructions que vous voulez tester, ou
disons que vous les chronométrez noyées dans le bruit. Votre programme
passe tout son temps dans les appels de fonctions, dans une moindre
mesure dans les printf(), et quelsues autres trucs.
- dans vos fonctions est_pairx(), mettre juste
return 0;
Si ça se trouve ce sera plus long ;-)
- virer le printf() dans test().
- remplacer le f(i * j) dans test() par l'une ou l'autre de vos
instructions.
- Alternativement, écrire une:
static int est_pair(int n) // ou static inline etc.
{
return !(n % 2);
}
et l'appeler directement dans test().
Puisque vous êtes sur l'optimisation, voyez le f(i*j) en fond de boucle.
Ça peut être coûteux et bien plus long (le bruit le bruit) que votre
instruction à tester, si le compilateur ne constate pas à votre place
que cette multiplication de deux valeurs non constantes n'est en fait
qu'un incrément.
Vous ne chronométrez pas les instructions que vous voulez tester, ou
disons que vous les chronométrez noyées dans le bruit. Votre programme
passe tout son temps dans les appels de fonctions, dans une moindre
mesure dans les printf(), et quelsues autres trucs.
- dans vos fonctions est_pairx(), mettre juste
return 0;
Si ça se trouve ce sera plus long ;-)
- virer le printf() dans test().
- remplacer le f(i * j) dans test() par l'une ou l'autre de vos
instructions.
- Alternativement, écrire une:
static int est_pair(int n) // ou static inline etc.
{
return !(n % 2);
}
et l'appeler directement dans test().
Puisque vous êtes sur l'optimisation, voyez le f(i*j) en fond de boucle.
Ça peut être coûteux et bien plus long (le bruit le bruit) que votre
instruction à tester, si le compilateur ne constate pas à votre place
que cette multiplication de deux valeurs non constantes n'est en fait
qu'un incrément.
(x % 2) en version signée est traduite comme
x - ((x + (((unsigned)x)>>31)) & ~1)
(en assumant du 32bit).
Donc VC effectue assez peu d'optim, il calcule (n % 2) puis le "not" du
résultat du modulo. En fait ce calcul du modulo fait par VC est une
version sans décalage, mais avec saut. Cela peut être intéressant
suivant le type de CPU.
La morale est qu'il vaut mieux clairement utiliser des unsigned pour les
manip bit-à-bits car "d'une façon générale", les compilos semblent être
mieux capables de mener les optims jusqu'au bout et produire un code asm
performant.
sam.
(x % 2) en version signée est traduite comme
x - ((x + (((unsigned)x)>>31)) & ~1)
(en assumant du 32bit).
Donc VC effectue assez peu d'optim, il calcule (n % 2) puis le "not" du
résultat du modulo. En fait ce calcul du modulo fait par VC est une
version sans décalage, mais avec saut. Cela peut être intéressant
suivant le type de CPU.
La morale est qu'il vaut mieux clairement utiliser des unsigned pour les
manip bit-à-bits car "d'une façon générale", les compilos semblent être
mieux capables de mener les optims jusqu'au bout et produire un code asm
performant.
sam.
(x % 2) en version signée est traduite comme
x - ((x + (((unsigned)x)>>31)) & ~1)
(en assumant du 32bit).
Donc VC effectue assez peu d'optim, il calcule (n % 2) puis le "not" du
résultat du modulo. En fait ce calcul du modulo fait par VC est une
version sans décalage, mais avec saut. Cela peut être intéressant
suivant le type de CPU.
La morale est qu'il vaut mieux clairement utiliser des unsigned pour les
manip bit-à-bits car "d'une façon générale", les compilos semblent être
mieux capables de mener les optims jusqu'au bout et produire un code asm
performant.
sam.
unsigned int i, j;
int s = 0;
clock_t start = clock ();
double ms;
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
s += f (i * j);
unsigned int i, j;
int s = 0;
clock_t start = clock ();
double ms;
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
s += f (i * j);
unsigned int i, j;
int s = 0;
clock_t start = clock ();
double ms;
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
s += f (i * j);
On 29 oct, 23:14, candide wrote:#define N (unsigned int)10000
Une façon compliqué et erronée
#define N ((unsigned int)10000)
d'écrire
#define N 10000U
On 29 oct, 23:14, candide <cand...@free.invalid> wrote:
#define N (unsigned int)10000
Une façon compliqué et erronée
#define N ((unsigned int)10000)
d'écrire
#define N 10000U
On 29 oct, 23:14, candide wrote:#define N (unsigned int)10000
Une façon compliqué et erronée
#define N ((unsigned int)10000)
d'écrire
#define N 10000U
On 29 oct, 23:14, candide wrote:printf("estpair%d : %.2lf secondesnn", j, duree/NB_TESTS);
N'existe pas.
C'est
printf("estpair%d : %.2f secondesnn", j, duree/NB_TESTS);
On 29 oct, 23:14, candide <cand...@free.invalid> wrote:
printf("estpair%d : %.2lf secondesnn", j, duree/NB_TESTS);
N'existe pas.
C'est
printf("estpair%d : %.2f secondesnn", j, duree/NB_TESTS);
On 29 oct, 23:14, candide wrote:printf("estpair%d : %.2lf secondesnn", j, duree/NB_TESTS);
N'existe pas.
C'est
printf("estpair%d : %.2f secondesnn", j, duree/NB_TESTS);
Samuel Devulder a écrit :(x % 2) en version signée est traduite comme
x - ((x + (((unsigned)x)>>31)) & ~1)
(en assumant du 32bit).
Ah ! OK donc, ce n'est quand même pas une brute division.
Donc VC effectue assez peu d'optim, il calcule (n % 2) puis le "not" du
résultat du modulo. En fait ce calcul du modulo fait par VC est une
version sans décalage, mais avec saut. Cela peut être intéressant
suivant le type de CPU.
Pas tout compris car connais pas l'assembleur.
sam <--> asm
un nom prédestiné quoi !!
Samuel Devulder a écrit :
(x % 2) en version signée est traduite comme
x - ((x + (((unsigned)x)>>31)) & ~1)
(en assumant du 32bit).
Ah ! OK donc, ce n'est quand même pas une brute division.
Donc VC effectue assez peu d'optim, il calcule (n % 2) puis le "not" du
résultat du modulo. En fait ce calcul du modulo fait par VC est une
version sans décalage, mais avec saut. Cela peut être intéressant
suivant le type de CPU.
Pas tout compris car connais pas l'assembleur.
sam <--> asm
un nom prédestiné quoi !!
Samuel Devulder a écrit :(x % 2) en version signée est traduite comme
x - ((x + (((unsigned)x)>>31)) & ~1)
(en assumant du 32bit).
Ah ! OK donc, ce n'est quand même pas une brute division.
Donc VC effectue assez peu d'optim, il calcule (n % 2) puis le "not" du
résultat du modulo. En fait ce calcul du modulo fait par VC est une
version sans décalage, mais avec saut. Cela peut être intéressant
suivant le type de CPU.
Pas tout compris car connais pas l'assembleur.
sam <--> asm
un nom prédestiné quoi !!
Pierre Maurette a écrit :
Vous ne chronométrez pas les instructions que vous voulez tester, ou
disons que vous les chronométrez noyées dans le bruit. Votre programme
passe tout son temps dans les appels de fonctions, dans une moindre
mesure dans les printf(), et quelsues autres trucs.
Certes, il y a du bruit mais je ne crois pas que ce soit gênant pour
discriminer puisque tous les tests font le même bruit.
Disons que ça va
juste changer les proportions de lenteur.
- dans vos fonctions est_pairx(), mettre juste
return 0;
Si ça se trouve ce sera plus long ;-)
Pas compris.
- virer le printf() dans test().
Il est bien pratique pour vérifier la conformité entre les tests mais on
peut réduire les affichages.
- remplacer le f(i * j) dans test() par l'une ou l'autre de vos
instructions.
Oui mais il faut bien que je fasse quelque chose d'utile (sinon les
optimisations peuvent ignorer les calculs) et d'assez long pour que ce
soit significatif.
- Alternativement, écrire une:
static int est_pair(int n) // ou static inline etc.
{
return !(n % 2);
}
et l'appeler directement dans test().
Jamais bien compris cet histoire de inlining
mais de toute façon, la
question ne va plus se poser puisque je vais réécrire les tests sans
appel de fonctions.
Puisque vous êtes sur l'optimisation, voyez le f(i*j) en fond de boucle.
Ça peut être coûteux et bien plus long (le bruit le bruit) que votre
Vous proposez quoi à la place car je n'ai pas beaucoup d'imagination ?
instruction à tester, si le compilateur ne constate pas à votre place
que cette multiplication de deux valeurs non constantes n'est en fait
qu'un incrément.
Comprends pas.
Pierre Maurette a écrit :
Vous ne chronométrez pas les instructions que vous voulez tester, ou
disons que vous les chronométrez noyées dans le bruit. Votre programme
passe tout son temps dans les appels de fonctions, dans une moindre
mesure dans les printf(), et quelsues autres trucs.
Certes, il y a du bruit mais je ne crois pas que ce soit gênant pour
discriminer puisque tous les tests font le même bruit.
Disons que ça va
juste changer les proportions de lenteur.
- dans vos fonctions est_pairx(), mettre juste
return 0;
Si ça se trouve ce sera plus long ;-)
Pas compris.
- virer le printf() dans test().
Il est bien pratique pour vérifier la conformité entre les tests mais on
peut réduire les affichages.
- remplacer le f(i * j) dans test() par l'une ou l'autre de vos
instructions.
Oui mais il faut bien que je fasse quelque chose d'utile (sinon les
optimisations peuvent ignorer les calculs) et d'assez long pour que ce
soit significatif.
- Alternativement, écrire une:
static int est_pair(int n) // ou static inline etc.
{
return !(n % 2);
}
et l'appeler directement dans test().
Jamais bien compris cet histoire de inlining
mais de toute façon, la
question ne va plus se poser puisque je vais réécrire les tests sans
appel de fonctions.
Puisque vous êtes sur l'optimisation, voyez le f(i*j) en fond de boucle.
Ça peut être coûteux et bien plus long (le bruit le bruit) que votre
Vous proposez quoi à la place car je n'ai pas beaucoup d'imagination ?
instruction à tester, si le compilateur ne constate pas à votre place
que cette multiplication de deux valeurs non constantes n'est en fait
qu'un incrément.
Comprends pas.
Pierre Maurette a écrit :
Vous ne chronométrez pas les instructions que vous voulez tester, ou
disons que vous les chronométrez noyées dans le bruit. Votre programme
passe tout son temps dans les appels de fonctions, dans une moindre
mesure dans les printf(), et quelsues autres trucs.
Certes, il y a du bruit mais je ne crois pas que ce soit gênant pour
discriminer puisque tous les tests font le même bruit.
Disons que ça va
juste changer les proportions de lenteur.
- dans vos fonctions est_pairx(), mettre juste
return 0;
Si ça se trouve ce sera plus long ;-)
Pas compris.
- virer le printf() dans test().
Il est bien pratique pour vérifier la conformité entre les tests mais on
peut réduire les affichages.
- remplacer le f(i * j) dans test() par l'une ou l'autre de vos
instructions.
Oui mais il faut bien que je fasse quelque chose d'utile (sinon les
optimisations peuvent ignorer les calculs) et d'assez long pour que ce
soit significatif.
- Alternativement, écrire une:
static int est_pair(int n) // ou static inline etc.
{
return !(n % 2);
}
et l'appeler directement dans test().
Jamais bien compris cet histoire de inlining
mais de toute façon, la
question ne va plus se poser puisque je vais réécrire les tests sans
appel de fonctions.
Puisque vous êtes sur l'optimisation, voyez le f(i*j) en fond de boucle.
Ça peut être coûteux et bien plus long (le bruit le bruit) que votre
Vous proposez quoi à la place car je n'ai pas beaucoup d'imagination ?
instruction à tester, si le compilateur ne constate pas à votre place
que cette multiplication de deux valeurs non constantes n'est en fait
qu'un incrément.
Comprends pas.
En fait c'est faux si x est signé.
En fait c'est faux si x est signé.
En fait c'est faux si x est signé.
Samuel Devulder, le 31/10/2009 a écrit :
[...]En fait c'est faux si x est signé.
Vous parlez d'assembleur. En fait la différence, c'est...
C'est un peu compliqué à expliquer.
Peut-être pas si compliqué que ça...
Ce que je veux dire, c'est qu'en C, les variables sont signées, et ça
fout un grosse merde. En assembleur, ce sont les opérateurs qui sont -
ou non - signés, et c'est bien plus simple.
Samuel Devulder, le 31/10/2009 a écrit :
[...]
En fait c'est faux si x est signé.
Vous parlez d'assembleur. En fait la différence, c'est...
C'est un peu compliqué à expliquer.
Peut-être pas si compliqué que ça...
Ce que je veux dire, c'est qu'en C, les variables sont signées, et ça
fout un grosse merde. En assembleur, ce sont les opérateurs qui sont -
ou non - signés, et c'est bien plus simple.
Samuel Devulder, le 31/10/2009 a écrit :
[...]En fait c'est faux si x est signé.
Vous parlez d'assembleur. En fait la différence, c'est...
C'est un peu compliqué à expliquer.
Peut-être pas si compliqué que ça...
Ce que je veux dire, c'est qu'en C, les variables sont signées, et ça
fout un grosse merde. En assembleur, ce sont les opérateurs qui sont -
ou non - signés, et c'est bien plus simple.