Я пытаюсь вывести большой вектор двойников параллельно, используя OpenMP. В настоящее время я пришел к следующему выводу:
#include <iomanip>
#include <iostream>
#include <sstream>
#include <string>
#include <omp.h>
#include <fstream>
int main()
{
int n = 10000000;
double* v = new double[n];
for (int i = 0; i < n; i++)
v[i] = (double)i;
int chunk;
std::ofstream filestream;
filestream.open("file", std::ios::binary | std::ios::out);
omp_set_num_threads(4);
double tic = omp_get_wtime(), toc;
#pragma omp parallel
{
int id = omp_get_thread_num();
if (id == 0) chunk = n / omp_get_num_threads(); //todo: assert that 4 threads have been set
double* vsub;
int start = id * chunk;
int end = (id + 1) * chunk - 1;
#pragma omp critical
{
std::cout << "Id = " << id << ", Chunk = " << chunk << ", start = " << start << ", end = " << end << '\n';
vsub = v + start;
}
std::stringstream ss;
ss << std::setprecision(6) << std::fixed;
for (int i = 0; i < end - start + 1; i++)
{
ss << vsub[i] << '\n';
}
std::string s = ss.str();
#pragma omp for ordered schedule(static, 1)
for (int t = 0; t < omp_get_num_threads(); ++t)
{
#pragma omp ordered
{
filestream.write(s.c_str(), s.size());
}
}
}
toc = omp_get_wtime();
printf("It took %f seconds to run\n", toc - tic);
getchar();
delete[] v;
filestream.close();
}
При использовании 1 потока время выполнения на моем рабочем столе составляет около 7,3 с, а при использовании 4 - 4,0 с. Я знаю, что при использовании буфера char вместо stringstream скорость улучшится, но я думаю, почему этот код не масштабируется нормально. Кстати, 95% времени уходит на создание строк, а не на запись в файл.