2017-03-20 5 views
0

compilateurs ++ mai C optimiser la boucle suivante à une boucle infiniemembre Optimisation de l'accès aux variables

this->m_stop=0; 
while(!this->m_stop) 
    { 
// do stuff 
    } 

Cette question est pertinente, même dans un contexte mono-thread, car un appel à l'intérieur de la boucle peut affecter l'indicateur d'état indirectement.

+0

Oui, un compilateur pourrait le faire. Vous pouvez l'éviter en rendant la variable 'volatile'. –

+3

pas si «faire les choses» modifie 'this-> m_stop' potentiellement –

+0

D'une manière générale, une optimisation est légale si, et seulement si, un programme conforme aux normes ne peut pas faire la différence dans le comportement garanti. –

Répondre

1

S'il n'y a aucune possibilité que le corps de la boucle puisse légitimement changer m_stop, alors ceci est une optimisation permise.

Si le compilateur ne peut pas voir le contenu des fonctions dans la boucle, alors il doit supposer qu'il peut changer m_stop.

Si un pointeur ou une référence à m_stop ou *this sont stockées quelque part accessible au code qui fonctionne dans le corps de la boucle, le compilateur devrait faire une analyse plus approfondie afin de déterminer s'il est sûr de supposer m_stop n » t changer. S'il ne peut pas faire cette analyse, alors il doit supposer que m_stop peut changer si le corps de la boucle change tout ce qui pourrait potentiellement se référer à m_stop.

-1

Si this->m_stop est non volatile et le compilateur peut savoir que la valeur de this->m_stop ne modifie pas sa valeur (c'est-à-dire que la condition sera toujours vraie).

Peut-être pourrait-il (dans certains cas) savoir que la condition restera vraie même si this->m_stop est volatile. Mais encore ce scénario signifie qu'il doit encore fondamentalement évaluer au moins this->m_stop pour chaque itération à travers la boucle (même si elle sait que le résultat sera 0). Normalement, un compilateur ne le saura pas.

Le cas où this->m_stop modifie sa valeur est une possibilité si le compilateur peut savoir que la valeur sera 0 à chaque démarrage de la boucle.

+0

Ne pas utiliser [std :: memory_order] (http://en.cppreference.com/w/cpp/atomic/memory_order) serait-il une meilleure option que «volatile»? –

+0

@JesperJuhl Cela dépend de l'objectif que je pense. 'volatile 'ne concerne pas la synchronisation de threads intre, mais plutôt l'ordre de fonctionnement intra-thread. – skyking

+2

@skyking volatile est à propos de variables qui peuvent être modifiées par des choses externes au programme ... l'utiliser pour d'autres threads est insuffisant et inutile –

1

Un compilateur ne peut effectuer que des optimisations qui n'affectent pas le comportement observable d'un programme bien formé. Ceci est communément appelé la règle as-if; le programme doit se comporter comme s'il était exécuté par une machine abstraite suivant la norme à la lettre, mais une implémentation peut changer les choses à propos de l'exécution pour la faire fonctionner plus vite tant que le programme agit de la même manière. En tant que tel, le compilateur ne peut pas optimiser votre code dans une boucle infinie à moins qu'il puisse prouver qu'il n'affecte pas le comportement observable du programme. Bien sûr, si vous avez un comportement indéfini quelque part, alors tous les paris sont désactivés.