web-dev-qa-db-fra.com

Comment empêcher gcc d'optimiser certaines déclarations en C?

Afin de rendre une page sale (activer le bit sale dans l'entrée du tableau de page), je touche les premiers octets de la page comme suit:

pageptr[0] = pageptr[0];

Mais en pratique, gcc ignorera la déclaration d'élimination des magasins morts. Afin d’empêcher l’optimisation de gcc, j’ai réécrit la déclaration comme suit:

volatile int tmp;
tmp = pageptr[0];
pageptr[0] = tmp;

Il semble que le truc marche, mais un peu moche. Je voudrais savoir s'il existe des directives ou une syntaxe ayant le même effet? Et je ne veux pas utiliser un -O0 drapeau, car il apportera également une pénalité de performance.

94
ZelluX

Désactiver l'optimisation résout le problème, mais il est inutile. Une alternative plus sûre consiste à rendre illégal pour le compilateur l'optimisation du magasin en utilisant le qualificateur de type volatile.

// Assuming pageptr is unsigned char * already...
unsigned char *pageptr = ...;
((unsigned char volatile *)pageptr)[0] = pageptr[0];

Le qualificateur de type volatile demande au compilateur d’être strict sur les magasins de mémoire et les charges. Un des objectifs de volatile est de faire savoir au compilateur que l'accès à la mémoire a des effets secondaires et qu'il doit donc être préservé. Dans ce cas, le magasin a pour effet secondaire de provoquer une erreur de page et vous souhaitez que le compilateur préserve l'erreur de page.

De cette façon, le code environnant peut toujours être optimisé et votre code est portable pour les autres compilateurs qui ne comprennent pas le #pragma ou __attribute__ syntaxe.

80
Dietrich Epp

Vous pouvez utiliser

#pragma GCC Push_options
#pragma GCC optimize ("O0")

your code

#pragma GCC pop_options

désactiver les optimisations depuis GCC 4.4.

Consultez la documentation de GCC si vous avez besoin de plus de détails.

167
Plow

Au lieu d'utiliser les nouveaux pragmas, vous pouvez également utiliser __attribute__((optimize("O0"))) pour vos besoins. Cela présente l'avantage de ne s'appliquer qu'à une seule fonction et non à toutes les fonctions définies dans le même fichier.

Exemple d'utilisation:

void __attribute__((optimize("O0"))) foo(unsigned char data) {
    // unmodifiable compiler code
}
118
FRob