pour la boucle ignorée (optimisée?) out

J’utilise des boucles for / while pour implémenter un délai dans mon code. La durée du délai n’a pas d’importance ici bien qu’elle soit suffisamment grande pour être perceptible. Voici l’extrait de code.

uint32_t i; // Do something useful for (i = 0; i < 50000000U; ++i) {} // Do something useful 

Le problème que j’observe est que cette boucle for ne sera pas exécutée. Il est probablement ignoré / optimisé par le compilateur. Cependant, si je qualifie le compteur de boucle i par volatile, la boucle for semble s’exécuter et je remarque le retard souhaité dans l’exécution.

Ce comportement semble un peu contre-intuitif à ma compréhension des optimisations du compilateur avec / sans le mot-clé volatile.

Même si le compteur de boucle est optimisé et stocké dans le registre du processeur, le compteur ne devrait-il pas continuer à fonctionner, peut-être avec un délai plus court? (Depuis, la surcharge de mémoire est supprimée.)

La plate-forme pour laquelle je construis est un processeur Xtensa (de Tensilica), et le compilateur C est celui fourni par Tensilica, le compilateur Xtensa C / C ++ fonctionnant avec le plus haut niveau d’optimisation.

J’ai essayé la même chose avec gcc 4.4.7 avec les niveaux d’optimisation -o3 et ofast. Le délai semble fonctionner dans ce cas.

Tout est question de comportement observable. Le seul comportement observable de votre boucle est que i est 50000000U après la boucle. Le compilateur est autorisé à l’optimiser et à le remplacer par i = 50000000U; . Cette affectation sera également optimisée car la valeur de i n’a aucune conséquence observable.

Le mot-clé volatile indique au compilateur que l’écriture et la lecture depuis i un comportement observable, l’empêchant ainsi de s’optimiser.

Le compilateur n’optimisera pas non plus les appels pour qu’il fonctionne sans access au code. Théoriquement, si un compilateur avait access à l’intégralité du code du système d’exploitation, il pourrait tout optimiser, à l’exception des variables volatiles, qui sont souvent associées à des opérations d’E / S matérielles.

Ces règles d’optimisation sont toutes conformes à ce qui est écrit dans la norme C ( cf. commentaires pour références ).

De plus, si vous souhaitez un délai, utilisez une fonction spécialisée (ex: API OS), ils sont fiables et ne consumnt pas de ressources processeur, contrairement à un délai de rotation comme le vôtre.