Я пробую свои силы в многопоточности в cpp11 и не могу понять, почему в следующем коде последовательная версия намного быстрее, чем параллельная.
Я понимаю, что в этом минимальном примере Функция вычисления не стоит распараллеливать, но я бы хотел использовать аналогичный подход для распараллеливания рендеринга пикселей в алгоритме RayTracing, в котором вычисление занимает гораздо больше времени, но я получаю такую же разницу в продолжительности в этом другом случае.
Полагаю, я что-то упустил из темы. Любая помощь или руководство будет высоко ценится.
#include <iostream>
#include <thread>
#include <vector>
#include <chrono>
void compute(double& res)
{
res = 2*res;
}
void computeSerial(std::vector<double>& res, const size_t& nPoints)
{
for (size_t i = 0; i < nPoints; i++)
{
compute(res[i]);
}
}
void computeParallel(std::vector<double>& res, const size_t& nPoints)
{
int numThreads = std::thread::hardware_concurrency() - 1;
std::vector<std::thread*> pool(numThreads, nullptr);
size_t nPointsComputed = 0;
while(nPointsComputed < nPoints)
{
size_t firstIndex = nPointsComputed;
for (size_t i = 0; i < numThreads; i++)
{
size_t index = firstIndex + i;
if(index < nPoints)
{
pool[i] = new std::thread(compute, std::ref(res[index]));
}
}
for (size_t i = 0; i < numThreads; i++)
{
size_t index = firstIndex + i;
if(index < nPoints)
{
pool[i]->join();
delete pool[i];
}
}
nPointsComputed += numThreads;
}
}
int main(void)
{
size_t pbSize = 1000;
std::vector<double> vSerial(pbSize, 0);
std::vector<double> vParallel(pbSize, 0);
for (size_t i = 0; i < pbSize; i++)
{
vSerial[i] = i;
vParallel[i] = i;
}
int numThreads = std::thread::hardware_concurrency();
std::cout << "Number of threads: " << numThreads << std::endl;
std::chrono::steady_clock::time_point begin, end;
begin = std::chrono::steady_clock::now();
computeSerial(vSerial, pbSize);
end = std::chrono::steady_clock::now();
std::cout << "duration serial = " << std::chrono::duration_cast<std::chrono::nanoseconds>(end - begin).count() << "[ns]" << std::endl;
begin = std::chrono::steady_clock::now();
computeParallel(vParallel, pbSize);
end = std::chrono::steady_clock::now();
std::cout << "duration parallel = " << std::chrono::duration_cast<std::chrono::nanoseconds>(end - begin).count() << "[ns]" << std::endl;
return 0;
}
После компиляции с clang++ -pthread main.cc
Я получаю следующий вывод:
Number of threads: 6
duration serial = 23561[µs]
duration parallel = 12219928[µs]
Последовательная версия значительно быстрее, чем параллельная , независимо от количества двойников для вычисления.