2010-01-22 4 views
5

Voici un code C++ auquel plusieurs threads accèdent en parallèle. Il a une section critique:Reclassement d'instructions avec des verrous

lock.Acquire(); 
current_id = shared_id; 
// small amounts of other code 
shared_id = (shared_id + 1) % max_id; 
lock.Release(); 
// do something with current_id 

La classe de la variable de verrouillage est wrapper autour de la mise en œuvre de mutex POSIX. En raison des opérations du module, il n'est pas possible d'utiliser des opérations atomiques.

Est-il possible qu'un compilateur gcc avec un indicateur O3 optimise le code afin que l'affectation de current_id soit déplacée avant le verrou?

Répondre

3

Il est possible de compiler avec O3!

Le compilateur n'optimisera jamais à travers un appel de fonction à moins que la fonction ne soit marquée comme pure en utilisant des attributs de fonction.

Les fonctions mutex ne sont pas pures, il est donc absolument sûr de les utiliser avec O3. Volatile n'empêche pas toutes les optimisations pertinentes.

+1

Vous voulez dire "à moins que la fonction est marquée comme pure ** ou le compilateur est en mesure de déterminer qu'il est sûr de le faire **. , le résultat final est le même, le compilateur ne fera pas une optimisation en général, sauf s'il peut vérifier qu'il est sûr – jalf

+0

Si 'current_id' et' shared_id' sont des variables locales qui n'ont pas échappé à la portée actuelle (adresse l'optimiseur pourrait bien réordonner ces lignes en ne tenant pas compte d'une possible mutation des appels de fonction externes, mais je suppose que ce n'est pas le cas ici, cependant – ephemient

+0

@ ephemient: mais s'ils sont locaux et non un à l'extérieur sait d'eux comment un appel de fonction externe pourrait les modifier? – Kosi2801

1

Normalement, le compilateur ne devrait pas faire de telles optimisations nuisibles. Si vous n'êtes toujours pas sûr, vous pouvez utiliser le mot clé volatile pour empêcher les optimisations sur ces variables d'identifiant.

+0

Il empêche la mise en cache de la valeur dans un registre, mais à peu près rien d'autre. Les lectures/écritures peuvent encore être réorganisées. – jalf

+0

Un bon traitement de quand utiliser volatile, dans le cadre de la documentation du noyau Linux: http://www.mjmwired.net/kernel/Documentation/volatile-considered-harmful.txt – asveikau

+0

@jalf: mais les compilateurs réorganisent-ils réellement les lectures/écrit pour qu'ils traversent la fonction-appel-limites? Les affectations et les appels de fonctions mélangés sont assez communs et je suppose qu'il y aurait beaucoup de problèmes partout si l'affectation des variables pouvait changer l'ordre avec des appels de fonction. – Kosi2801

Questions connexes