Режим выпуска пропускает части кода - PullRequest
4 голосов
/ 27 января 2012

При попытке проверить скорость функций я обнаружил, что не все части моего кода работают в режиме Release. Этот же код отлично работает в режиме Debug.

Я использую компилятор VC ++ с оптимизацией /O2.

Вот вырезанная часть, которая не работает.

int main()
{
    boost::timer::auto_cpu_timer t;

    for(int i = 0; i < 1000000; i++)
        gcdb(i, 5);
    return 0;
}

Сгенерированная сборка в режиме выпуска, код для цикла for отсутствует только в этом режиме.

int main()
{
000000013F8E1280  sub         rsp,88h  
000000013F8E1287  mov         rax,qword ptr [__security_cookie (013F8E7150h)]  
000000013F8E128E  xor         rax,rsp  
000000013F8E1291  mov         qword ptr [rsp+70h],rax  
    boost::timer::auto_cpu_timer t;
000000013F8E1296  lea         rcx,[t]  
000000013F8E129B  mov         edx,6  
000000013F8E12A0  call        boost::timer::auto_cpu_timer::auto_cpu_timer (013F8E2DA0h)  

    for(int i = 0; i < 1000000; i++)
        gcdb(i, 5);
    return 0;
000000013F8E12A5  lea         rcx,[t]  
000000013F8E12AA  call        boost::timer::auto_cpu_timer::~auto_cpu_timer (013F8E2810h)  
000000013F8E12AF  xor         eax,eax  
}

gcdb() - это просто функция для нахождения GCD двух чисел.

Что может быть причиной пропуска этого кода?

Ответы [ 2 ]

8 голосов
/ 27 января 2012

Здесь вы видите оптимизацию компилятора, известную как Устранение мертвого кода .

Когда компилятор видит, что результат некоторого кода не нужен, его можно удалить бесплатноЭто.Это стандартная оптимизация, используемая всеми современными компиляторами.

Обходной путь, не позволяющий компилятору оптимизировать его, заключается в том, чтобы фактически использовать выходные данные некоторым образом:

int main()
{
    boost::timer::auto_cpu_timer t;

    int sum = 0;

    for(int i = 0; i < 1000000; i++)
        sum += gcdb(i, 5);

    cout << sum << endl;
    return 0;
}

Как GCC оптимизирует неиспользуемую переменную, увеличенную в цикле?

2 голосов
/ 27 января 2012

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

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

...