Итак, я написал программу, которая генерирует изображение Мандельброта. Затем я решил написать его так, чтобы ускорить его с помощью указанного количества потоков. Вот что я придумал:
void mandelbrot_all(std::vector<std::vector<int>>& pixels, int X, int Y, int threadCount) {
using namespace std;
vector<thread> threads;
int numThreads = threadCount;
for(int i=0; i<numThreads; i++) {
threads.push_back(thread (mandelbrot_range, std::ref(pixels), i*X/numThreads, 0, X*(i+1)/numThreads, Y, X));
}
for(int i=0; i<numThreads; i++) {
threads[i].join();
}
}
Намерение состояло в том, чтобы разделить обработку на куски и обработать каждый отдельно. Когда я запускаю программу, в качестве аргумента она принимает число, которое будет использоваться как число потоков, которые будут использоваться в программе для этого запуска. К сожалению, я получаю похожие времена для любого количества потоков.
Есть ли что-то о потоке в C ++, что мне не хватает? Нужно ли добавлять что-то или шаблон какого-то рода, чтобы потоки работали одновременно? Или способ, которым я делаю темы, просто глуп?
Я попытался запустить этот код на Raspberry Pi и моем четырехъядерном ноутбуке, с такими же результатами.
Любая помощь будет оценена.
Я немного опаздываю к этому вопросу, но, оглядываясь назад, я помню решение: я программировал на одноядерном Raspberry Pi. Одно ядро означает отсутствие ускорения от потоков.
Я думаю, что порождение темы слишком дорого, вы можете попробовать PPL или же TBB. которые оба имеют Parallel_for и Parallel_foreach, и используют их для циклического прохождения пикселей вместо использования потоков. они внутренне управляют потоками, поэтому у вас меньше накладных расходов и больше пропускной способности.
Решение одной проблемы за раз, почему бы не попробовать и жестко закодировать использование 2 потоков, а затем 3? Запуск потока стоит дорого, однако, если вы запустите только 2 потока и рассчитаете довольно большой Мандельброт, тогда время запуска потока будет относительно нулевым.
До тех пор, пока вы не достигнете 2-кратного и 3-кратного ускорения, у вас есть другие проблемы, которые вам нужно отладить & решить, отдельно.
Не глядя на ваш код и не играя с ним, трудно точно определить, в чем именно заключается проблема. Но вот предположение: некоторые части изображения множества Мандельброта гораздо проще вычислить, чем другие. Ваш код разрезает изображение на равные фрагменты по оси X, но большая часть работы (скажем, 70%) может попасть в один фрагмент. В этом случае лучшее, что вы можете сделать, — это увеличить скорость на 30%, так как остальным потокам все еще приходится ждать завершения последнего. Например, если вы работаете с четырьмя потоками и разрезаете изображение на четыре части, третий фрагмент, безусловно, выглядит более интенсивным, чем остальные. Конечно, 70% это только оценка.