简体   繁体   English

vs2010 c ++尾调用优化

[英]vs2010 c++ tail call optimization

Consider the following code: 请考虑以下代码:

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;
}

According to generated asm file everything is ok, tail call is optimized. 根据生成的asm文件一切正常,尾调用优化。

Try to replace 尝试更换

int x = fac( 50 );

with

int x = fac_aux( 50, 1 );

Strange enough, but tail call optimization is disappeared. 奇怪,但尾调用优化消失了。 As far as I remember there was no such a strange compiler behaviour in VS2008. 据我所知,在VS2008中没有这么奇怪的编译器行为。 Any ideas why these things happen and how to be sure of tail call optimization is done? 任何有关这些事情发生的想法以及如何确保尾部调用优化都已完成?

; ; Function compile flags: /Ogtp 函数编译标志:/ Ogtp

Tried both /O2 and /Ox optimization flags. 尝试了/ O2和/ Ox优化标志。 Are there any other compiler options that matter? 是否有其他重要的编译器选项?

Edit : VS2012 manages to do the optimization 编辑 :VS2012设法进行优化

I tried the following code 我尝试了以下代码

#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;
}

and used the full optimization /Ox but I did not get the tail recursion. 并使用完全优化/牛,但我没有得到尾递归。 So it seems that MS VC++ 2010 does not support the tail recursion. 所以似乎MS VC ++ 2010不支持尾递归。

when the original is compiled, the assembly at the callsite has partial inlining of fac_aux , specifically the x - 1 part, which is required for the tail recursion, but using fac_aux prevents the partial inlining and thus the tail recursion optimization: 当原始编译时,为调用该组件具有的局部内联fac_aux ,特别是x - 1部分,这是需要的尾递归,但使用fac_aux防止局部内联,因此尾递归优化:

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

尝试明确inline函数 - 此外,您使用的是什么优化级别?

我不知道它是否会起作用,但尝试用单个return语句替换if ... else:

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

Looks weird, are you doing some kind of incremental compile. 看起来很奇怪,你在做某种增量编译吗? Other than that, it might be the fact that compiler gets confused by the multiple parameters, in the working version there's effectively only one parameter, somehow the optimization doesn't qualify anymore. 除此之外,可能是编译器被多个参数搞糊涂的事实,在工作版本中实际上只有一个参数,不知怎样,优化不再符合条件。

You could try making the res parameter a global, I its know messy bad practice, but it might work. 您可以尝试将res参数设置为全局,我知道这是一个非常糟糕的不良做法,但它可能会起作用。

Sounds like a compiler bug/feature. 听起来像编译器错误/功能。

/Tony /托尼

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM