2010-01-22 16 views
5

Aquí se accede al código C++ desde varios subprocesos en paralelo. Tiene una sección crítica:Reordenación de estado con bloqueos

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 clase de la variable de bloqueo es envoltorio alrededor de la implementación de mutex POSIX. Debido a las operaciones del módulo, no es posible usar operaciones atómicas.

¿Es posible que un compilador gcc con un indicador O3 optimice el código para que la asignación de current_id se mueva antes del bloqueo?

Respuesta

3

¡Es posible compilar con O3!

El compilador nunca optimizará a través de una llamada de función a menos que la función esté marcada como pura usando atributos de función.

Las funciones mutex no son puras, por lo que es absolutamente seguro usarlas con O3.

+1

Quiere decir "a menos que la función esté marcada como pura ** o el compilador pueda determinar que es seguro hacerlo **. Por supuesto , el resultado final es el mismo, el compilador no hará una optimización en general, a menos que pueda verificar que es seguro. – jalf

+0

Si 'current_id' y' shared_id' son ambas variables locales que no han escapado del alcance actual (dirección no se le ha dado a nadie más, etc.) entonces el optimizador bien podría reordenar esas líneas sin tener en cuenta la posible mutación de las llamadas a funciones externas. Supongo que no es el caso aquí. – ephemient

+0

@ephemient: pero si son locales y no uno en el exterior sabe de ellos, ¿cómo podría una función externa llamar a modificarlos? – Kosi2801

1

Normalmente, el compilador no debería realizar optimizaciones tan perjudiciales. Si aún no está seguro, podría usar la palabra clave volatile para evitar optimizaciones en esas variables de id.

+0

volátil no impide todas las optimizaciones relevantes. Impide que el valor se guarde en caché en un registro, pero prácticamente nada más. Las lecturas/escrituras aún se pueden reordenar. – jalf

+0

Un buen tratamiento sobre cuándo usar volátiles, como parte de la documentación del kernel de Linux: http://www.mjmwired.net/kernel/Documentation/volatile-considered-harmful.txt – asveikau

+0

@jalf: pero los compiladores realmente reordenan las lecturas/escribe para que crucen la función-call-boundaries? Las asignaciones y llamadas a funciones mezcladas son bastante comunes y supongo que habría muchos problemas por todas partes si la asignación de variables pudiera cambiar el orden con llamadas a funciones. – Kosi2801

Cuestiones relacionadas