Трудности с измерением производительности C / C ++

Я написал фрагмент кода на C, чтобы показать точку в обсуждении оптимизации и прогнозирования ветвлений. Тогда я заметил еще более разнообразный исход, чем ожидал. Моя цель состояла в том, чтобы написать его на языке, который является общим подмножеством между C ++ и C, который совместим со стандартами для обоих языков и который достаточно переносим. Он был протестирован на разных ПК с Windows:

#include <stdio.h>
#include <time.h>

/// @return - time difference between start and stop in milliseconds
int ms_elapsed( clock_t start, clock_t stop )
{
    return (int)( 1000.0 * ( stop - start ) / CLOCKS_PER_SEC );
}

int const Billion = 1000000000;
/// & with numbers up to Billion gives 0, 0, 2, 2 repeating pattern 
int const Pattern_0_0_2_2 = 0x40000002; 

/// @return - half of Billion  
int unpredictableIfs()
{
    int sum = 0;
    for ( int i = 0; i < Billion; ++i )
    {
        // true, true, false, false ...
        if ( ( i & Pattern_0_0_2_2 ) == 0 )
        {
            ++sum;
        }
    }
    return sum;
}

/// @return - half of Billion  
int noIfs()
{
    int sum = 0;
    for ( int i = 0; i < Billion; ++i )
    {
        // 1, 1, 0, 0 ...
        sum += ( i & Pattern_0_0_2_2 ) == 0;
    }
    return sum;
}

int main()
{
    clock_t volatile start;
    clock_t volatile stop;
    int volatile sum;
    printf( "Puzzling measurements:\n" );

    start = clock();
    sum = unpredictableIfs();
    stop = clock();
    printf( "Unpredictable ifs took %d msec; answer was %d\n"
          , ms_elapsed(start, stop), sum );

    start = clock();
    sum = unpredictableIfs();
    stop = clock();
    printf( "Unpredictable ifs took %d msec; answer was %d\n"
          , ms_elapsed(start, stop), sum );

    start = clock();
    sum = noIfs();
    stop = clock();
    printf( "Same without ifs took %d msec; answer was %d\n"
          , ms_elapsed(start, stop), sum );

    start = clock();
    sum = unpredictableIfs();
    stop = clock();
    printf( "Unpredictable ifs took %d msec; answer was %d\n"
          , ms_elapsed(start, stop), sum );
}

Составлено с VS2010; / O2 оптимизации Intel Core 2, WinXP результаты:

Puzzling measurements:
Unpredictable ifs took 1344 msec; answer was 500000000
Unpredictable ifs took 1016 msec; answer was 500000000
Same without ifs took 1031 msec; answer was 500000000
Unpredictable ifs took 4797 msec; answer was 500000000

Редактировать: Полные переключатели компилятора:

/ Zi / nologo / W3 / WX- / O2 / Oi / Oy- / GL / D "WIN32" / D "NDEBUG" / D "_CONSOLE" / D "_UNICODE" / D "UNICODE" / Gm- / EHsc / GS / Gy / fp: точный / Zc: wchar_t / Zc: forScope /Fp"Release\Tiring.pch "/ Fa" Release \ "/ Fo" Release \ "/Fd"Release\vc100.pdb" / Gd / analysis- / errorReport: очереди

Другой человек написал такое ... Скомпилировано с MinGW, g ++ 4.71, оптимизация -O1 Intel Core 2, WinXP:

Puzzling measurements:
Unpredictable ifs took 1656 msec; answer was 500000000
Unpredictable ifs took 0 msec; answer was 500000000
Same without ifs took 1969 msec; answer was 500000000
Unpredictable ifs took 0 msec; answer was 500000000

Также он опубликовал такие результаты для оптимизации -O3:

Puzzling measurements:
Unpredictable ifs took 1890 msec; answer was 500000000
Unpredictable ifs took 2516 msec; answer was 500000000
Same without ifs took 1422 msec; answer was 500000000
Unpredictable ifs took 2516 msec; answer was 500000000

Теперь у меня есть вопрос. Что здесь происходит?

Более конкретно ... Как фиксированная функция может занимать так много времени? Что-то не так в моем коде? Есть ли что-то хитрое с процессором Intel? Компиляторы делают что-то странное? Может ли это быть из-за того, что 32-битный код работает на 64-битном процессоре?

Спасибо за внимание!

Редактировать: Я принимаю, что g ++ -O1 просто повторно использует возвращенные значения в 2 других вызовах. Я также признаю, что g ++ -O2 и g ++ -O3 имеют дефект, который не учитывает оптимизацию. Значительное разнообразие измеренных скоростей (450% !!!) кажется все еще загадочным.

Я посмотрел на разборку кода, созданного VS2010. Это встроенныйunpredictableIfs три раза. Встроенный код был довольно похож; петля была такая же. Не встроенныйnoIfs, Это действительно катилосьnoIfs немного. Это занимает 4 шага за одну итерацию.noIfs рассчитать, как было написано в то время какunpredictableIfs использованиеjne перепрыгнуть через шаг.

Ответы на вопрос(3)

Ваш ответ на вопрос