vs2010 c ++ оптимизация хвостового вызова - PullRequest
10 голосов
/ 08 марта 2011

Рассмотрим следующий код:

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

В соответствии с созданным файлом asm все в порядке, хвостовой вызов оптимизирован.

Попробуйте заменить

int x = fac( 50 );

int x = fac_aux( 50, 1 );

Довольно странно, но оптимизация хвостового вызова исчезла.Насколько я помню, в VS2008 такого странного поведения компилятора не было.Любые идеи, почему эти вещи происходят и как быть уверенными в оптимизации хвостового вызова, сделаны?

;Флаги компиляции функции: / Ogtp

Пробовал оба флага оптимизации / O2 и / Ox.Существуют ли другие важные параметры компилятора?

Редактировать : VS2012 удается оптимизировать

Ответы [ 5 ]

1 голос
/ 31 июля 2012

, когда оригинал компилируется, сборка на месте вызова имеет частичное встраивание 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
1 голос
/ 31 июля 2012

Я попробовал следующий код

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

и использовал полную оптимизацию / Ox, но я не получил хвостовую рекурсию.Похоже, что MS VC ++ 2010 не поддерживает хвостовую рекурсию.

0 голосов
/ 08 марта 2011

Я не знаю, сработает ли это, но попробуйте заменить if ... else на одно выражение return:

return (x == 1) ? res : fac_aux( x - 1, res * x );
0 голосов
/ 28 сентября 2011

Выглядит странно, вы делаете какую-то пошаговую компиляцию.Кроме того, это может быть тот факт, что компилятор запутывается из-за нескольких параметров, в рабочей версии фактически есть только один параметр, так как оптимизация больше не подходит.

Вы можете попробовать сделать параметр resглобальный, я знаю, что это грязная плохая практика, но она может работать.

Звучит как ошибка / функция компилятора.

/ Tony

0 голосов
/ 08 марта 2011

Попробуйте сделать функции явно inline - более того, какой уровень оптимизации вы используете?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...