c++ visual-studio-2010 visual-c++ tail-call-optimization

vs2010 c++ optimización de la cola de cola



visual-studio-2010 visual-c++ (5)

Intente hacer explícitamente las funciones en inline ; además, ¿qué nivel de optimización está usando?

Considera el siguiente código:

int fac_aux( int x, int res ) { if( x == 1 ) return res; else return fac_aux( x - 1, res * x ); } int fac( int x ) { return fac_aux( x, 1 ); } int main() { int x = fac( 50 ); std::cout << x; return 0; }

De acuerdo con el archivo asm generado todo está bien, la cola de llamada está optimizada.

Intenta reemplazar

int x = fac( 50 );

con

int x = fac_aux( 50, 1 );

Es bastante extraño, pero la optimización de la cola de llamada ha desaparecido. Por lo que recuerdo, no había un comportamiento de compilación tan extraño en VS2008. ¿Alguna idea de por qué ocurren estas cosas y cómo asegurarse de que se haga una optimización de las llamadas finales?

; Banderas de compilación de funciones: / Ogtp

Intentó los indicadores de optimización de ambos / O2 y / Ox. ¿Hay alguna otra opción de compilación que importe?

Editar : VS2012 logra hacer la optimización


No sé si funcionará, pero intente reemplazar si ... else con declaración de devolución única:

return (x == 1) ? res : fac_aux( x - 1, res * x );


Parece extraño, ¿estás haciendo algún tipo de compilación incremental? Aparte de eso, podría ser el hecho de que el compilador se confunde por los múltiples parámetros, en la versión de trabajo hay efectivamente un solo parámetro, de alguna manera la optimización ya no califica.

Podrías tratar de hacer que el parámetro res sea global, es una mala práctica desordenada, pero podría funcionar.

Suena como una característica / error del compilador.

/ Tony


Probé el siguiente código

#include "stdafx.h" int f( size_t i, int x ) { return ( ( i < 2 ) ? x : f( i - 1, i * x ) ); } int f( size_t i ) { return ( f( i, 1 ) ); } int _tmain(int argc, _TCHAR* argv[]) { { f( 0 ); } return 0; }

y usé la optimización completa / Ox pero no obtuve la recursividad de la cola. Parece que MS VC ++ 2010 no admite la recursividad de cola.


cuando se compila el original, el ensamblado en el callsite tiene una delimitación parcial de fac_aux , específicamente la parte x - 1 , que se requiere para la recursión fac_aux , pero el uso de fac_aux evita la fac_aux parcial y, por lo tanto, la optimización de recursión de cola:

TestThin.fac_aux 013B1000 CMP ECX,1 013B1003 JE SHORT TestThin.013B100E 013B1005 IMUL EAX,ECX 013B1008 DEC ECX 013B1009 CMP ECX,1 013B100C JNZ SHORT TestThin.013B1005 013B100E RETN 013B100F INT3 TestThin.main 013B1010 MOV EAX,32 013B1015 LEA ECX,DWORD PTR DS:[EAX-1] ;notice the partial inlining of x - 1 013B1018 CALL TestThin.fac_aux