Я пытался вычислить производительность некоторого низкоуровневого ассемблерного кода, созданного компилятором. Однако в какой-то момент я получил странные результаты, которых я не понимаю. Итак, вот мой код:
#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 я каждый раз получал этот странный шаблон, и он всегда один и тот же.
Итак, я хочу спросить, не поврежден ли мой код, я что-то упустил? А может это просто странное поведение компилятора?
Очень важно правильно измерять время при любом тестировании, поэтому я не хочу ошибаться с самого начала.