Ответ
Задача: Параллельное вычисление суммы элементов большого вектора.
Идея: Разделить вектор на несколько частей (по числу потоков), вычислить частичные суммы в каждом потоке параллельно, а затем сложить результаты в главном потоке.
Реализация на C++ с использованием <thread> и <future>:
#include <iostream>
#include <vector>
#include <thread>
#include <future>
#include <numeric>
#include <chrono>
// Функция для вычисления частичной суммы в диапазоне [begin, end)
int partial_sum(const std::vector<int>& data, size_t begin, size_t end) {
return std::accumulate(data.begin() + begin, data.begin() + end, 0);
}
int main() {
const size_t dataSize = 100'000'000;
const int numThreads = std::thread::hardware_concurrency(); // Кол-во ядер CPU
// 1. Генерируем большой вектор данных
std::vector<int> bigData(dataSize, 1); // Вектор из единиц, сумма = dataSize
// 2. Делим работу на диапазоны для потоков
std::vector<std::future<int>> futures;
size_t chunkSize = dataSize / numThreads;
auto start = std::chrono::high_resolution_clock::now();
// 3. Запускаем асинхронные задачи (потоки) через std::async
for (int i = 0; i < numThreads; ++i) {
size_t begin = i * chunkSize;
size_t end = (i == numThreads - 1) ? dataSize : begin + chunkSize;
// Запускаем вычисление частичной суммы в отдельном потоке
futures.emplace_back(std::async(std::launch::async, partial_sum, std::ref(bigData), begin, end));
}
// 4. Собираем (редуцируем) результаты
int totalSum = 0;
for (auto& fut : futures) {
totalSum += fut.get(); // get() блокирует, пока поток не вернёт результат
}
auto end = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
std::cout << "Total sum: " << totalSum << std::endl;
std::cout << "Time taken with " << numThreads << " threads: " << duration.count() << " ms" << std::endl;
// 5. Для сравнения — последовательная версия
start = std::chrono::high_resolution_clock::now();
int sequentialSum = std::accumulate(bigData.begin(), bigData.end(), 0);
end = std::chrono::high_resolution_clock::now();
duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
std::cout << "Sequential time: " << duration.count() << " ms" << std::endl;
return 0;
}
Ключевые элементы C++ в примере:
std::thread::hardware_concurrency()— получение числа поддерживаемых аппаратно потоков.std::async— высокоуровневый способ запуска асинхронной задачи, возвращающийstd::future.std::future— объект для получения результата из асинхронной операции.std::ref()— передача ссылки на вектор в поток (по умолчанию аргументы копируются).
Почему это хороший пример: Задача легко распараллеливается (data parallelism), нет гонок данных (data races), так как каждый поток работает со своим диапазоном, и наглядно виден выигрыш в производительности на многоядерном процессоре.