C ++ - Странные измерения времени с Visual Studio - PullRequest
0 голосов
/ 10 мая 2018

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

#include <iostream>
#include <chrono>
#include <vector>

//---------------------------------------------------------------------------------------

int main()
{
    std::srand(time(NULL));
    constexpr unsigned vectorSize = 1000u;
    constexpr unsigned loopCount = 1000000u;
    std::vector<int> vec1(vectorSize);
    std::vector<int> vec2(vectorSize);
    for (unsigned i = 0u; i < vectorSize; ++i)
    {
        vec1[i] = std::rand();
    }
    for (unsigned i = 0u; i < vectorSize; ++i)
    {
        vec2[i] = std::rand();
    }

    std::chrono::time_point<std::chrono::high_resolution_clock> start;
    std::chrono::time_point<std::chrono::high_resolution_clock> end;
    long long ms;

    //---------------------------------------------------------------------------------------
    start = std::chrono::high_resolution_clock::now();

    for (unsigned j = 0u; j < loopCount; ++j)
    {
        for (unsigned i = 0u; i < vec2.size(); ++i)
        {
            vec2[i] = vec1[i];
        }
    }

    end = std::chrono::high_resolution_clock::now();
    ms = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
    std::cout << "Evaluation took: " << ms << " ms" << std::endl;

    //---------------------------------------------------------------------------------------

    start = std::chrono::high_resolution_clock::now();

    for (unsigned j = 0u; j < loopCount; ++j)
    {
        for (unsigned i = 0u; i < vec2.size(); ++i)
        {
            vec2[i] = vec1[i];
        }
    }

    end = std::chrono::high_resolution_clock::now();
    ms = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
    std::cout << "Evaluation took: " << ms << " ms" << std::endl;

    //---------------------------------------------------------------------------------------

    start = std::chrono::high_resolution_clock::now();

    for (unsigned j = 0u; j < loopCount; ++j)
    {
        for (unsigned i = 0u; i < vec2.size(); ++i)
        {
            vec2[i] = vec1[i];
        }
    }

    end = std::chrono::high_resolution_clock::now();
    ms = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
    std::cout << "Evaluation took: " << ms << " ms" << std::endl;

    //---------------------------------------------------------------------------------------

    start = std::chrono::high_resolution_clock::now();

    for (unsigned j = 0u; j < loopCount; ++j)
    {
        for (unsigned i = 0u; i < vec2.size(); ++i)
        {
            vec2[i] = vec1[i];
        }
    }

    end = std::chrono::high_resolution_clock::now();
    ms = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
    std::cout << "Evaluation took: " << ms << " ms" << std::endl;

    //---------------------------------------------------------------------------------------

    start = std::chrono::high_resolution_clock::now();

    for (unsigned j = 0u; j < loopCount; ++j)
    {
        for (unsigned i = 0u; i < vec2.size(); ++i)
        {
            vec2[i] = vec1[i];
        }
    }

    end = std::chrono::high_resolution_clock::now();
    ms = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
    std::cout << "Evaluation took: " << ms << " ms" << std::endl;

    //---------------------------------------------------------------------------------------

    std::cout << "Press enter to exit..." << std::endl;
    std::cin.get();
    return 0;
}

Основная «работа» в этой программе выполняется в цикле, где элементы вектора vec1 просто присваиваются вектору vec2. Внутреннее условие цикла предназначено для запрета компиляции для оптимизации SIMD. Я повторил код 5 раз, скопировав его, поэтому ожидал получить более или менее одинаковое измерение времени для каждой отдельной копии. Тем не менее, результаты разные:

Оценка заняла: 425 мс
Оценка заняла: 694 мс
Оценка заняла: 462 мс
Оценка заняла: 441 мс
Оценка заняла: 710 мс
Нажмите Enter, чтобы выйти ...

Так выглядит после сборки с помощью Visual Studio 2015 в режиме выпуска. Удивительно, но с GCC вычисленные времена очень похожи, но с Visual я каждый раз получал этот странный шаблон, и он всегда один и тот же.

Итак, я хочу спросить, не поврежден ли мой код, я что-то упустил? А может это просто странное поведение компилятора? Очень важно правильно измерять время при любом тестировании, поэтому я не хочу ошибаться с самого начала.

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