Рассмотрим этот код:
#include <algorithm>
#include <chrono>
#include <cstdio>
#include <execution>
#include <functional>
#include <random>
#include <vector>
using namespace std;
using namespace std::chrono;
constexpr size_t NUM_OF_ELEMENTS = 30000000;
// execute lambda and print the execution time
void measure(function<void()> lambda)
{
auto start = high_resolution_clock::now();
lambda();
auto end = high_resolution_clock::now();
printf("%ld\n", duration_cast<microseconds>(end - start).count());
}
int main()
{
random_device rd;
mt19937_64 gen(rd());
// range from INT_MIN to INT_MAX
uniform_int_distribution<> distr(-2147483648, 2147483647);
vector<int> original;
original.reserve(NUM_OF_ELEMENTS);
for(size_t i = 0; i < NUM_OF_ELEMENTS; i++)
original.push_back(distr(gen));
vector<int> the_copy(original.begin(), original.end());
// sort with single thread
measure([&]{ sort(original.begin(), original.end()); });
// sort with execution::par
measure([&]{ sort(execution::par, the_copy.begin(), the_copy.end()); });
return 0;
}
Код можно суммировать в несколько пунктов:
- создать генератор случайных чисел
- создать вектор случайных чисел целые числа
- создать копию этого вектора
- отсортировать исходный вектор с помощью одного потока и измерить время выполнения
- отсортировать копию с помощью
std::execution::par
и измерить время выполнения - распечатать время выполнения
Версия execution::par
всегда занимает больше времени. Неважно, какое значение имеет NUM_OF_ELEMENTS
. Я пробовал значения от 100 000 до 30 000 000, увеличиваясь на 100 000. Приведенный выше код дает похожие результаты (значения в микросекундах):
9729406 // single thread
10834613 // execution::par
Я скомпилировал код на Windows 10 с помощью g cc с использованием кода VS: g++ -std=c++17 -g ${workspaceFolder}/main.cpp -o ${workspaceFolder}/main.exe
Для стандартной библиотеки C ++ я использую дистрибутив mingw, который можно найти здесь . Версии программы: GCC 10.1.0 + LLVM/Clang/LLD/LLDB 10.0.0 + MinGW-w64 7.0.0
У моего процессора 6 ядер, и во время выполнения я не запускал никаких основных программ или фоновых процессов.
Во-первых, я подумал, что ему есть чем заняться при размере вектора но 30 000 000 элементов наверняка хватит. Он уже работает в течение 10 секунд перед завершением одного теста.
- Что происходит?
- Разве
execution::par
предназначен для использования таким образом? - Сделать Мне нужно включить некоторые флаги компиляции или какой-то другой трюк, чтобы он работал должным образом?