Le rapport avec ma question précédente "Ça se fait,ça ?" n'est
imaginaire.
Je connais les règles de base sur l'optimisation code source, en gros,
vu sur la toile:
(1) Don't do it.
(2) (For experts only!) Don't do it yet.
Néanmoins, il est des cas qui ressemblent à de la contre-optimisation.
En particulier si je sais des choses sur une donnée - non constante -
que le compilateur ne peut intégrer dans sa démarche.
void func(/* ... */, size_t val)
{
/*
du code dans lequel val est utilisé lourdement,
à la fois dans des offset et dans des bornes de boucles
*/
}
Le compilateur va générer le code en considérant que val peut prendre
toutes les valeurs du type. Mais moi, je *sais* que val ne pourra
prendre que les valeurs 1 et 3. Et je vois clairement qu'il sera plus
efficace de dupliquer tout le code, une fois en remplaçant val par
(size_t)1, une fois par (size_t)3, avec un test de tête. Sans même
parler de duplication de la fonction.
Je sais bien que la norme laisse liberté au compilateur de générer du
code pour peu que le résultat soit celui que le programmeur est en
droit d'attendre. Mais d'un autre coté le programmeur est en droit
d'attendre un minimum de qualité.
Y-a-t-il un moyen reconnu de faire passer l'information au compilateur
avec un maximum de chances que le message passe ?
Dans ce cas précis, faire de val une enum ? Introduire dans la fonction
ou ailleurs un:
const size_t val[] = {1, 3};
Ou alors, solution plus générale (on peut avoir une inégalité, ou
l'indication d'une congruence à 4 par exemple):
assert(val == 1 || val == 3);
ou
assert((val % 4) == 0);
Je serais moi-même compilateur, c'est la solution de l'assert() qui me
conviendrait le mieux.
J'ai fait (trop ?) rapidement des tests avec gcc, il semble qu'il s'en
tamponne le coquillard, de mon assert().
Ou alors, solution plus générale (on peut avoir une inégalité, ou l'indication d'une congruence à 4 par exemple): assert(val == 1 || val == 3); ou assert((val % 4) == 0);
Je serais moi-même compilateur, c'est la solution de l'assert() qui me conviendrait le mieux.
Ouaip, ils n'ont pas du tout suivi cette voie, ils ont prefere rajouter plein de cochonneries dependant du compilo. J'ai oublie la syntaxe exacte, mais c'est des __attribute__ qui permettent de dire si telle branche du test sera prise ou pas...
j'avoue etre d'accord avec toi, c'est plutot dommage de ne pas utiliser directement assert, qui fait partie de la norme et qui pourrait etre utilise pour de l'optimisation... il y a certainement eu une grosse discussion dans la ml gcc sur le pourquoi et le comment, et le fait que ca allait casser des trucs.
Vu les conneries qu'ils ont deja fait ces dernieres annees (la plus belle etant sans doute de virer les memcpy a 0 "inutiles"... du beau travail pour le code cryptographique), ils n'en etaient pourtant plus a une pres...
In article <mn.8ab17d7623a118b8.31483@laposte.net>,
Pierre Maurette <maurettepierre@wanadoo.fr> wrote:
Ou alors, solution plus générale (on peut avoir une inégalité, ou
l'indication d'une congruence à 4 par exemple):
assert(val == 1 || val == 3);
ou
assert((val % 4) == 0);
Je serais moi-même compilateur, c'est la solution de l'assert() qui me
conviendrait le mieux.
Ouaip, ils n'ont pas du tout suivi cette voie, ils ont prefere rajouter
plein de cochonneries dependant du compilo. J'ai oublie la syntaxe
exacte, mais c'est des __attribute__ qui permettent de dire si telle branche
du test sera prise ou pas...
j'avoue etre d'accord avec toi, c'est plutot dommage de ne pas utiliser
directement assert, qui fait partie de la norme et qui pourrait etre
utilise pour de l'optimisation... il y a certainement eu une grosse
discussion dans la ml gcc sur le pourquoi et le comment, et le fait que
ca allait casser des trucs.
Vu les conneries qu'ils ont deja fait ces dernieres annees (la plus belle
etant sans doute de virer les memcpy a 0 "inutiles"... du beau travail
pour le code cryptographique), ils n'en etaient pourtant plus a une
pres...
Ou alors, solution plus générale (on peut avoir une inégalité, ou l'indication d'une congruence à 4 par exemple): assert(val == 1 || val == 3); ou assert((val % 4) == 0);
Je serais moi-même compilateur, c'est la solution de l'assert() qui me conviendrait le mieux.
Ouaip, ils n'ont pas du tout suivi cette voie, ils ont prefere rajouter plein de cochonneries dependant du compilo. J'ai oublie la syntaxe exacte, mais c'est des __attribute__ qui permettent de dire si telle branche du test sera prise ou pas...
j'avoue etre d'accord avec toi, c'est plutot dommage de ne pas utiliser directement assert, qui fait partie de la norme et qui pourrait etre utilise pour de l'optimisation... il y a certainement eu une grosse discussion dans la ml gcc sur le pourquoi et le comment, et le fait que ca allait casser des trucs.
Vu les conneries qu'ils ont deja fait ces dernieres annees (la plus belle etant sans doute de virer les memcpy a 0 "inutiles"... du beau travail pour le code cryptographique), ils n'en etaient pourtant plus a une pres...
espie
In article <467581ae$0$5083$, Harpo wrote:
On Sun, 17 Jun 2007 10:08:45 +0000, Marc Espie wrote:
Vu les conneries qu'ils ont deja fait ces dernieres annees (la plus belle etant sans doute de virer les memcpy a 0 "inutiles"...
Qu'est-ce que c'est ?
J'ai ecrit memcpy en pensant memset, en fait. memset fait partie de la norme, c'est donc une fonction magique. Dans les versions recentes, gcc remplace systematiquement memset par des boucles (ce qui occasionne son lot de problemes dans des cas d'alignement un peu bizarres... ca encore c'est pas trop grave).
La ou ca pose vraiment probleme, c'est sur un cas d'utilisation assez courant, style:
void f() { char passwd[250]; // code qui demande un mot de passe a l'utilisateur. // code qui s'en sert memset(passwd, 0, sizeof passwd); }
comme passwd est une variable locale, non utilisee ailleurs, gcc decrete que le memset ne sert a rien... et hop, un passwd dans la nature.
In article <467581ae$0$5083$ba4acef3@news.orange.fr>,
Harpo <invalid@invalid.invalid> wrote:
On Sun, 17 Jun 2007 10:08:45 +0000, Marc Espie wrote:
Vu les conneries qu'ils ont deja fait ces dernieres annees (la plus belle
etant sans doute de virer les memcpy a 0 "inutiles"...
Qu'est-ce que c'est ?
J'ai ecrit memcpy en pensant memset, en fait.
memset fait partie de la norme, c'est donc une fonction magique.
Dans les versions recentes, gcc remplace systematiquement memset par
des boucles (ce qui occasionne son lot de problemes dans des cas d'alignement
un peu bizarres... ca encore c'est pas trop grave).
La ou ca pose vraiment probleme, c'est sur un cas d'utilisation assez
courant, style:
void
f()
{
char passwd[250];
// code qui demande un mot de passe a l'utilisateur.
// code qui s'en sert
memset(passwd, 0, sizeof passwd);
}
comme passwd est une variable locale, non utilisee ailleurs, gcc decrete
que le memset ne sert a rien... et hop, un passwd dans la nature.
On Sun, 17 Jun 2007 10:08:45 +0000, Marc Espie wrote:
Vu les conneries qu'ils ont deja fait ces dernieres annees (la plus belle etant sans doute de virer les memcpy a 0 "inutiles"...
Qu'est-ce que c'est ?
J'ai ecrit memcpy en pensant memset, en fait. memset fait partie de la norme, c'est donc une fonction magique. Dans les versions recentes, gcc remplace systematiquement memset par des boucles (ce qui occasionne son lot de problemes dans des cas d'alignement un peu bizarres... ca encore c'est pas trop grave).
La ou ca pose vraiment probleme, c'est sur un cas d'utilisation assez courant, style:
void f() { char passwd[250]; // code qui demande un mot de passe a l'utilisateur. // code qui s'en sert memset(passwd, 0, sizeof passwd); }
comme passwd est une variable locale, non utilisee ailleurs, gcc decrete que le memset ne sert a rien... et hop, un passwd dans la nature.
Thierry B.
--{ Marc Espie a plopé ceci: }--
void f() { char passwd[250]; // code qui demande un mot de passe a l'utilisateur. // code qui s'en sert memset(passwd, 0, sizeof passwd); }
comme passwd est une variable locale, non utilisee ailleurs, gcc decrete que le memset ne sert a rien... et hop, un passwd dans la nature.
Sans déc' ? Là, ces jours-ci, je suis en train de gruiker un "serveur" d'authentification, et j'avais classé le memset dans les axiomes de base. Tu pourrais fournir un ECM qu'on puisse tous tester chez nous pour voir l'étendue des dégats ?
-- "Low cost, stand-alone, easy to use". The trigone of computing.
--{ Marc Espie a plopé ceci: }--
void
f()
{
char passwd[250];
// code qui demande un mot de passe a l'utilisateur.
// code qui s'en sert
memset(passwd, 0, sizeof passwd);
}
comme passwd est une variable locale, non utilisee ailleurs, gcc decrete
que le memset ne sert a rien... et hop, un passwd dans la nature.
Sans déc' ? Là, ces jours-ci, je suis en train de gruiker un
"serveur" d'authentification, et j'avais classé le memset dans
les axiomes de base. Tu pourrais fournir un ECM qu'on puisse
tous tester chez nous pour voir l'étendue des dégats ?
--
"Low cost, stand-alone, easy to use". The trigone of computing.
void f() { char passwd[250]; // code qui demande un mot de passe a l'utilisateur. // code qui s'en sert memset(passwd, 0, sizeof passwd); }
comme passwd est une variable locale, non utilisee ailleurs, gcc decrete que le memset ne sert a rien... et hop, un passwd dans la nature.
Sans déc' ? Là, ces jours-ci, je suis en train de gruiker un "serveur" d'authentification, et j'avais classé le memset dans les axiomes de base. Tu pourrais fournir un ECM qu'on puisse tous tester chez nous pour voir l'étendue des dégats ?
-- "Low cost, stand-alone, easy to use". The trigone of computing.
Pierre Maurette
[...]
void f() { char passwd[250]; // code qui demande un mot de passe a l'utilisateur. // code qui s'en sert memset(passwd, 0, sizeof passwd); }
comme passwd est une variable locale, non utilisee ailleurs, gcc decrete que le memset ne sert a rien... et hop, un passwd dans la nature.
Vous pourriez essayer:
void f() { volatile char passwd[250]; // code qui demande un mot de passe a l'utilisateur. // code qui s'en sert memset(passwd, 0, sizeof passwd); }
La logique du volatile (piou piou), en gros à mon sens dire au compilateur "T'arrêtes de faire le beau et de réfléchir à ma place, sur cette variable, tu fais ce que je te dis de faire et au moment où je te le dis, non mais !", voudrait que memset() soit appelé. Mais la logique de gcc, parfois...
-- Pierre Maurette
[...]
void
f()
{
char passwd[250];
// code qui demande un mot de passe a l'utilisateur.
// code qui s'en sert
memset(passwd, 0, sizeof passwd);
}
comme passwd est une variable locale, non utilisee ailleurs, gcc decrete
que le memset ne sert a rien... et hop, un passwd dans la nature.
Vous pourriez essayer:
void
f()
{
volatile char passwd[250];
// code qui demande un mot de passe a l'utilisateur.
// code qui s'en sert
memset(passwd, 0, sizeof passwd);
}
La logique du volatile (piou piou), en gros à mon sens dire au
compilateur "T'arrêtes de faire le beau et de réfléchir à ma place, sur
cette variable, tu fais ce que je te dis de faire et au moment où je te
le dis, non mais !", voudrait que memset() soit appelé.
Mais la logique de gcc, parfois...
void f() { char passwd[250]; // code qui demande un mot de passe a l'utilisateur. // code qui s'en sert memset(passwd, 0, sizeof passwd); }
comme passwd est une variable locale, non utilisee ailleurs, gcc decrete que le memset ne sert a rien... et hop, un passwd dans la nature.
Vous pourriez essayer:
void f() { volatile char passwd[250]; // code qui demande un mot de passe a l'utilisateur. // code qui s'en sert memset(passwd, 0, sizeof passwd); }
La logique du volatile (piou piou), en gros à mon sens dire au compilateur "T'arrêtes de faire le beau et de réfléchir à ma place, sur cette variable, tu fais ce que je te dis de faire et au moment où je te le dis, non mais !", voudrait que memset() soit appelé. Mais la logique de gcc, parfois...
-- Pierre Maurette
Xavier Roche
comme passwd est une variable locale, non utilisee ailleurs, gcc decrete que le memset ne sert a rien... et hop, un passwd dans la nature.
Je n'ai pas le problème sous gcc à priori (version 3.3 ou 4.1)
comme passwd est une variable locale, non utilisee ailleurs, gcc decrete
que le memset ne sert a rien... et hop, un passwd dans la nature.
Je n'ai pas le problème sous gcc à priori (version 3.3 ou 4.1)
comme passwd est une variable locale, non utilisee ailleurs, gcc decrete que le memset ne sert a rien... et hop, un passwd dans la nature.
Je n'ai pas le problème sous gcc à priori (version 3.3 ou 4.1)
rixed
On 2007-06-17, Pierre Maurette wrote:
Le compilateur va générer le code en considérant que val peut prendre toutes les valeurs du type. Mais moi, je *sais* que val ne pourra prendre que les valeurs 1 et 3. Et je vois clairement qu'il sera plus efficace de dupliquer tout le code, une fois en remplaçant val par (size_t)1, une fois par (size_t)3, avec un test de tête. Sans même parler de duplication de la fonction.
Je sais bien que la norme laisse liberté au compilateur de générer du code pour peu que le résultat soit celui que le programmeur est en droit d'attendre. Mais d'un autre coté le programmeur est en droit d'attendre un minimum de qualité.
Y-a-t-il un moyen reconnu de faire passer l'information au compilateur avec un maximum de chances que le message passe ?
Je m'étonnes de ne pas avoir vu de réponse de la part des participant versés dans les arcannes de gcc, mais je crois que gcc est capable de se rendre compte tout seul que la fonction ne sera appelée qu'avec seulement deux valeurs différente et d'en tenir compte pour générer du code plus spécifique. En gros, le fonctionnement serait le suivant :
- compiler le programme une première fois avec les options qui vont bien pour que le code compilé inclue du code qui sauvegarde des statistiques, entre autres les valeurs les plus courantes des paramètres d'entrée des fonctions
- exécuter le programme "suffisament"
- recompiler le programme avec en entrée supplémentaire les statistiques en questions.
Le programme résultant devrait inclure des versions spécialisées de ta fonction pour les valeur 1 et 3.
Ne connaissant pas plus de détail sur la procédure, ce résumé insatisfaisant n'a pour fonction que de faire sortir de leur réserve ceux qui savent vraiment comment ça marche et comment on s'en sert.
Sinon, il me semble que ta question élude une partie importante du problème : comment faire passer l'info non pas au compilateur, mais au programmeur qui va relire. Pour ça, j'ai un penchant personnel pour l'enum ; qui règle également la question des performances dans ce cas, je pense.
On 2007-06-17, Pierre Maurette <maurettepierre@wanadoo.fr> wrote:
Le compilateur va générer le code en considérant que val peut prendre
toutes les valeurs du type. Mais moi, je *sais* que val ne pourra
prendre que les valeurs 1 et 3. Et je vois clairement qu'il sera plus
efficace de dupliquer tout le code, une fois en remplaçant val par
(size_t)1, une fois par (size_t)3, avec un test de tête. Sans même
parler de duplication de la fonction.
Je sais bien que la norme laisse liberté au compilateur de générer du
code pour peu que le résultat soit celui que le programmeur est en
droit d'attendre. Mais d'un autre coté le programmeur est en droit
d'attendre un minimum de qualité.
Y-a-t-il un moyen reconnu de faire passer l'information au compilateur
avec un maximum de chances que le message passe ?
Je m'étonnes de ne pas avoir vu de réponse de la part des participant
versés dans les arcannes de gcc, mais je crois que gcc est capable
de se rendre compte tout seul que la fonction ne sera appelée qu'avec
seulement deux valeurs différente et d'en tenir compte pour générer du
code plus spécifique. En gros, le fonctionnement serait le suivant :
- compiler le programme une première fois avec les options qui vont bien
pour que le code compilé inclue du code qui sauvegarde des statistiques,
entre autres les valeurs les plus courantes des paramètres d'entrée des
fonctions
- exécuter le programme "suffisament"
- recompiler le programme avec en entrée supplémentaire les statistiques
en questions.
Le programme résultant devrait inclure des versions spécialisées de ta
fonction pour les valeur 1 et 3.
Ne connaissant pas plus de détail sur la procédure, ce résumé
insatisfaisant n'a pour fonction que de faire sortir de leur réserve
ceux qui savent vraiment comment ça marche et comment on s'en sert.
Sinon, il me semble que ta question élude une partie importante du
problème : comment faire passer l'info non pas au compilateur, mais au
programmeur qui va relire. Pour ça, j'ai un penchant personnel pour
l'enum ; qui règle également la question des performances dans ce cas, je
pense.
Le compilateur va générer le code en considérant que val peut prendre toutes les valeurs du type. Mais moi, je *sais* que val ne pourra prendre que les valeurs 1 et 3. Et je vois clairement qu'il sera plus efficace de dupliquer tout le code, une fois en remplaçant val par (size_t)1, une fois par (size_t)3, avec un test de tête. Sans même parler de duplication de la fonction.
Je sais bien que la norme laisse liberté au compilateur de générer du code pour peu que le résultat soit celui que le programmeur est en droit d'attendre. Mais d'un autre coté le programmeur est en droit d'attendre un minimum de qualité.
Y-a-t-il un moyen reconnu de faire passer l'information au compilateur avec un maximum de chances que le message passe ?
Je m'étonnes de ne pas avoir vu de réponse de la part des participant versés dans les arcannes de gcc, mais je crois que gcc est capable de se rendre compte tout seul que la fonction ne sera appelée qu'avec seulement deux valeurs différente et d'en tenir compte pour générer du code plus spécifique. En gros, le fonctionnement serait le suivant :
- compiler le programme une première fois avec les options qui vont bien pour que le code compilé inclue du code qui sauvegarde des statistiques, entre autres les valeurs les plus courantes des paramètres d'entrée des fonctions
- exécuter le programme "suffisament"
- recompiler le programme avec en entrée supplémentaire les statistiques en questions.
Le programme résultant devrait inclure des versions spécialisées de ta fonction pour les valeur 1 et 3.
Ne connaissant pas plus de détail sur la procédure, ce résumé insatisfaisant n'a pour fonction que de faire sortir de leur réserve ceux qui savent vraiment comment ça marche et comment on s'en sert.
Sinon, il me semble que ta question élude une partie importante du problème : comment faire passer l'info non pas au compilateur, mais au programmeur qui va relire. Pour ça, j'ai un penchant personnel pour l'enum ; qui règle également la question des performances dans ce cas, je pense.
espie
In article <f558t8$f3t$, Xavier Roche wrote:
comme passwd est une variable locale, non utilisee ailleurs, gcc decrete que le memset ne sert a rien... et hop, un passwd dans la nature.
Je n'ai pas le problème sous gcc à priori (version 3.3 ou 4.1)
Tu n'as juste pas une version suffisamment recente... quand je disais que ca bougeait beaucoup.
In article <f558t8$f3t$1@news.httrack.net>,
Xavier Roche <xroche@free.fr.NOSPAM.invalid> wrote:
comme passwd est une variable locale, non utilisee ailleurs, gcc decrete
que le memset ne sert a rien... et hop, un passwd dans la nature.
Je n'ai pas le problème sous gcc à priori (version 3.3 ou 4.1)
Tu n'as juste pas une version suffisamment recente... quand je disais
que ca bougeait beaucoup.
comme passwd est une variable locale, non utilisee ailleurs, gcc decrete que le memset ne sert a rien... et hop, un passwd dans la nature.
Je n'ai pas le problème sous gcc à priori (version 3.3 ou 4.1)
Tu n'as juste pas une version suffisamment recente... quand je disais que ca bougeait beaucoup.
espie
In article , Pierre Maurette wrote:
[...]
void f() { char passwd[250]; // code qui demande un mot de passe a l'utilisateur. // code qui s'en sert memset(passwd, 0, sizeof passwd); }
comme passwd est une variable locale, non utilisee ailleurs, gcc decrete que le memset ne sert a rien... et hop, un passwd dans la nature.
Vous pourriez essayer:
void f() { volatile char passwd[250]; // code qui demande un mot de passe a l'utilisateur. // code qui s'en sert memset(passwd, 0, sizeof passwd); }
La logique du volatile (piou piou), en gros à mon sens dire au compilateur "T'arrêtes de faire le beau et de réfléchir à ma place, sur cette variable, tu fais ce que je te dis de faire et au moment où je te le dis, non mais !", voudrait que memset() soit appelé. Mais la logique de gcc, parfois...
En fait, non, ca ne suffit pas, pour deux raisons. - d'abord, memset ne prend pas des parametres volatile. Donc stricto sensu, il y a eu un cast, et c'est pas du tout evident de savoir si memset devrait prendre en compte le volatile ou pas (plus les references sous la main, mais ce genre de trucs a ete discute sur les ml gcc). - ensuite, c'est brutalement inefficace, puisque toutes les autres operations sur passwd vont utiliser le cote volatile de la bestiole... Comme, assez souvent, on va vouloir faire `quelques' calculs sur passwd (genre, evaluation d'un hash cryptographique), on risque de se manger un facteur 10 dans les dents, a un endroit qui n'en a pas forcement besoin...
Il y a un flag: -fno-builtin-memset, mais c'est un peu tout ou rien, sur la totalite des utilisations de memset dans une unite de compilation (et ca desactive pas mal d'optimisations utiles, elles).
In article <mn.91cb7d76b06d499b.31483@laposte.net>,
Pierre Maurette <maurettepierre@wanadoo.fr> wrote:
[...]
void
f()
{
char passwd[250];
// code qui demande un mot de passe a l'utilisateur.
// code qui s'en sert
memset(passwd, 0, sizeof passwd);
}
comme passwd est une variable locale, non utilisee ailleurs, gcc decrete
que le memset ne sert a rien... et hop, un passwd dans la nature.
Vous pourriez essayer:
void
f()
{
volatile char passwd[250];
// code qui demande un mot de passe a l'utilisateur.
// code qui s'en sert
memset(passwd, 0, sizeof passwd);
}
La logique du volatile (piou piou), en gros à mon sens dire au
compilateur "T'arrêtes de faire le beau et de réfléchir à ma place, sur
cette variable, tu fais ce que je te dis de faire et au moment où je te
le dis, non mais !", voudrait que memset() soit appelé.
Mais la logique de gcc, parfois...
En fait, non, ca ne suffit pas, pour deux raisons.
- d'abord, memset ne prend pas des parametres volatile. Donc stricto
sensu, il y a eu un cast, et c'est pas du tout evident de savoir
si memset devrait prendre en compte le volatile ou pas (plus les
references sous la main, mais ce genre de trucs a ete discute sur
les ml gcc).
- ensuite, c'est brutalement inefficace, puisque toutes les autres
operations sur passwd vont utiliser le cote volatile de la bestiole...
Comme, assez souvent, on va vouloir faire `quelques' calculs sur passwd
(genre, evaluation d'un hash cryptographique), on risque de se manger
un facteur 10 dans les dents, a un endroit qui n'en a pas forcement
besoin...
Il y a un flag: -fno-builtin-memset, mais c'est un peu tout ou rien,
sur la totalite des utilisations de memset dans une unite de compilation
(et ca desactive pas mal d'optimisations utiles, elles).
void f() { char passwd[250]; // code qui demande un mot de passe a l'utilisateur. // code qui s'en sert memset(passwd, 0, sizeof passwd); }
comme passwd est une variable locale, non utilisee ailleurs, gcc decrete que le memset ne sert a rien... et hop, un passwd dans la nature.
Vous pourriez essayer:
void f() { volatile char passwd[250]; // code qui demande un mot de passe a l'utilisateur. // code qui s'en sert memset(passwd, 0, sizeof passwd); }
La logique du volatile (piou piou), en gros à mon sens dire au compilateur "T'arrêtes de faire le beau et de réfléchir à ma place, sur cette variable, tu fais ce que je te dis de faire et au moment où je te le dis, non mais !", voudrait que memset() soit appelé. Mais la logique de gcc, parfois...
En fait, non, ca ne suffit pas, pour deux raisons. - d'abord, memset ne prend pas des parametres volatile. Donc stricto sensu, il y a eu un cast, et c'est pas du tout evident de savoir si memset devrait prendre en compte le volatile ou pas (plus les references sous la main, mais ce genre de trucs a ete discute sur les ml gcc). - ensuite, c'est brutalement inefficace, puisque toutes les autres operations sur passwd vont utiliser le cote volatile de la bestiole... Comme, assez souvent, on va vouloir faire `quelques' calculs sur passwd (genre, evaluation d'un hash cryptographique), on risque de se manger un facteur 10 dans les dents, a un endroit qui n'en a pas forcement besoin...
Il y a un flag: -fno-builtin-memset, mais c'est un peu tout ou rien, sur la totalite des utilisations de memset dans une unite de compilation (et ca desactive pas mal d'optimisations utiles, elles).
Vincent Lefevre
Dans l'article <f55qed$10ac$, Marc Espie écrit:
En fait, non, ca ne suffit pas, pour deux raisons. - d'abord, memset ne prend pas des parametres volatile. Donc stricto sensu, il y a eu un cast, et c'est pas du tout evident de savoir si memset devrait prendre en compte le volatile ou pas (plus les references sous la main, mais ce genre de trucs a ete discute sur les ml gcc). - ensuite, c'est brutalement inefficace, puisque toutes les autres operations sur passwd vont utiliser le cote volatile de la bestiole... Comme, assez souvent, on va vouloir faire `quelques' calculs sur passwd (genre, evaluation d'un hash cryptographique), on risque de se manger un facteur 10 dans les dents, a un endroit qui n'en a pas forcement besoin...
Tu peux remplacer le memset par une boucle utilisant volatile (via un cast ou une affectation de pointeur).
De toute façon, il te faudra faire des choses non standard pour être sûr que la page mémoire ne doit pas être placée sur disque (swap).
Dans l'article <f55qed$10ac$2@biggoron.nerim.net>,
Marc Espie <espie@lain.home> écrit:
En fait, non, ca ne suffit pas, pour deux raisons.
- d'abord, memset ne prend pas des parametres volatile. Donc stricto
sensu, il y a eu un cast, et c'est pas du tout evident de savoir
si memset devrait prendre en compte le volatile ou pas (plus les
references sous la main, mais ce genre de trucs a ete discute sur
les ml gcc).
- ensuite, c'est brutalement inefficace, puisque toutes les autres
operations sur passwd vont utiliser le cote volatile de la bestiole...
Comme, assez souvent, on va vouloir faire `quelques' calculs sur passwd
(genre, evaluation d'un hash cryptographique), on risque de se manger
un facteur 10 dans les dents, a un endroit qui n'en a pas forcement
besoin...
Tu peux remplacer le memset par une boucle utilisant volatile (via
un cast ou une affectation de pointeur).
De toute façon, il te faudra faire des choses non standard pour être
sûr que la page mémoire ne doit pas être placée sur disque (swap).
En fait, non, ca ne suffit pas, pour deux raisons. - d'abord, memset ne prend pas des parametres volatile. Donc stricto sensu, il y a eu un cast, et c'est pas du tout evident de savoir si memset devrait prendre en compte le volatile ou pas (plus les references sous la main, mais ce genre de trucs a ete discute sur les ml gcc). - ensuite, c'est brutalement inefficace, puisque toutes les autres operations sur passwd vont utiliser le cote volatile de la bestiole... Comme, assez souvent, on va vouloir faire `quelques' calculs sur passwd (genre, evaluation d'un hash cryptographique), on risque de se manger un facteur 10 dans les dents, a un endroit qui n'en a pas forcement besoin...
Tu peux remplacer le memset par une boucle utilisant volatile (via un cast ou une affectation de pointeur).
De toute façon, il te faudra faire des choses non standard pour être sûr que la page mémoire ne doit pas être placée sur disque (swap).