programas programar programa paso funciones estructuras ejemplos como comandos c++ optimization

programar - funciones en c++ pdf



¿Por qué los compiladores de C++ no optimizan esta asignación booleana condicional como una asignación incondicional? (3)

Considere la siguiente función:

void func(bool& flag) { if(!flag) flag=true; }

Me parece que si flag tiene un valor booleano válido, esto sería equivalente a establecerlo como true incondicional, así:

void func(bool& flag) { flag=true; }

Sin embargo, ni gcc ni clang lo optimizan de esta manera; ambos generan lo siguiente en el nivel de optimización -O3 :

_Z4funcRb: .LFB0: .cfi_startproc cmp BYTE PTR [rdi], 0 jne .L1 mov BYTE PTR [rdi], 1 .L1: rep ret

Mi pregunta es: ¿es solo que el código es un caso demasiado especial como para preocuparse por optimizarlo, o hay alguna buena razón por la cual dicha optimización no sería deseada, dado que el flag no es una referencia a volatile ? Parece que la única razón que podría ser es que la flag alguna manera podría tener un valor no true o false sin un comportamiento indefinido en el momento de leerlo, pero no estoy seguro de si esto es posible.


Aparte de la respuesta de Leon sobre el rendimiento:

Supongamos que la flag es true . Supongamos que dos hilos llaman constantemente a func(flag) . La función como está escrita, en ese caso, no almacena nada para flag , por lo que debería ser seguro para subprocesos. Dos hilos acceden a la misma memoria, pero solo para leerla. Establecer incondicionalmente el flag en true significa que dos hilos diferentes estarían escribiendo en la misma memoria. Esto no es seguro, esto no es seguro incluso si los datos que se escriben son idénticos a los datos que ya están allí.


Esto puede afectar negativamente el rendimiento del programa debido a consideraciones de coherencia de caché . Escribir para flag cada vez que se llama a func() ensuciaría la línea de caché que contiene. Esto sucederá independientemente del hecho de que el valor que se está escribiendo coincide exactamente con los bits encontrados en la dirección de destino antes de la escritura.

EDITAR

hvd ha proporcionado otra buena razón que impide dicha optimización. Es un argumento más convincente contra la optimización propuesta, ya que puede dar lugar a un comportamiento indefinido, mientras que mi respuesta (original) solo aborda aspectos de rendimiento.

Después de un poco más de reflexión, puedo proponer un ejemplo más de por qué los compiladores deberían estar fuertemente prohibidos, a menos que puedan probar que la transformación es segura para un contexto particular, de introducir la escritura incondicional. Considera este código:

const bool foo = true; int main() { func(const_cast<bool&>(foo)); }

Con una escritura incondicional en func() esto definitivamente desencadena un comportamiento indefinido (la escritura en la memoria de solo lectura finalizará el programa, incluso si el efecto de la escritura sería no operativo).


No estoy seguro sobre el comportamiento de C ++ aquí, pero en C la memoria puede cambiar porque si la memoria contiene un valor distinto de cero, que no sea 1, se mantendrá sin cambios con la verificación, pero cambiará a 1 con la verificación.

Pero como no soy muy fluido en C ++, no sé si esta situación es posible.