c++ performance const-correctness

c++ - ¿Puede la corrección constante mejorar el rendimiento?



performance const-correctness (4)

Sí puede.

La mayoría de las const son puramente para el beneficio del programador y no ayudan a que el compilador se optimice porque es legal desecharlas y, por lo tanto, no le dicen al compilador nada útil para la optimización. Sin embargo, algunas const no pueden ser eliminadas (legalmente) y estas proporcionan al compilador información útil para la optimización.

Como ejemplo, el acceso a una variable global definida con un tipo const puede estar en línea mientras que una sin un tipo const no puede estar en línea porque podría cambiar en tiempo de ejecución.

https://godbolt.org/g/UEX4NB

C ++:

int foo1 = 1; const int foo2 = 2; int get_foo1() { return foo1; } int get_foo2() { return foo2; }

asm

foo1: .long 1 foo2: .long 2 get_foo1(): push rbp mov rbp, rsp mov eax, DWORD PTR foo1[rip] ; foo1 must be accessed by address pop rbp ret get_foo2(): push rbp mov rbp, rsp mov eax, 2 ; foo2 has been replaced with an immediate 2 pop rbp ret

En términos prácticos, tenga en cuenta que, si bien la const puede mejorar el rendimiento, en la mayoría de los casos no lo hará o lo hará, pero el cambio no se notará. La utilidad primaria de const no es la optimización.

Steve Jessop da otro ejemplo en su comentario sobre la pregunta original que muestra algo que vale la pena mencionar. En un ámbito de bloque, es posible que un compilador deduzca si una variable se mutará y se optimizará en consecuencia, independientemente de la const , porque el compilador puede ver todos los usos de la variable. En contraste, en el ejemplo anterior, es imposible predecir si foo1 se foo1 ya que podría modificarse en otras unidades de traducción. Supongo que un hipotético compilador de ultra podría analizar un programa completo y determinar si es válido para el acceso en línea a foo1 ... pero los compiladores reales no pueden.

He leído varias veces que hacer cumplir la corrección constante en su código C o C ++ no solo es una buena práctica con respecto a la capacidad de mantenimiento, sino que también le permite al compilador realizar optimizaciones. Sin embargo, también he leído todo lo contrario, que no afecta en absoluto al rendimiento.

Por lo tanto, ¿tiene ejemplos en los que la corrección constante puede ayudar a su compilador a mejorar el rendimiento de su programa?



en mi experiencia, no

Para las variables escalares, el compilador puede determinar cada vez que se cambia el valor y realizar la optimización necesaria.

Para los punteros de matriz, la corrección constante no garantiza que los valores sean realmente constantes en presencia de posibles problemas de aliasing. Por lo tanto, el compilador no puede usar el modificador const solo para realizar optimizaciones

Si está buscando optimización, debe considerar __restrict__ o modificadores / atributos de funciones especiales: http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html


const corrección de const no puede mejorar el rendimiento porque const_cast y mutable están en el idioma y permiten que el código rompa las reglas de manera conforme. Esto empeora aún más en C ++ 11, donde los datos const pueden ser, por ejemplo, un puntero a std::atomic , lo que significa que el compilador debe respetar los cambios realizados por otros subprocesos.

Dicho esto, es trivial para el compilador observar el código que genera y determinar si realmente escribe en una variable determinada y aplica las optimizaciones en consecuencia.

Dicho todo esto, la corrección const es algo bueno con respecto a la mantenibilidad. De lo contrario, los clientes de su clase podrían romper los miembros internos de esa clase. Por ejemplo, considere el estándar std::string::c_str() - si no pudiera devolver un valor constante, ¡sería capaz de joder con el búfer interno de la cadena!

No use const por razones de rendimiento. Úsalo por razones de mantenibilidad.