#c #multithreading
Вопрос:
я пытаюсь нарисовать Мандельброта и хочу использовать 4 угрозы для выполнения вычисления одновременно , но в другой части изображения, вот функции
void Mandelbrot(int x_min,int x_max,int y_min,int y_max,Image amp;im)
{
for (int i = y_min; i < y_max; i )
{
for (int j = x_min; j < x_max; j )
{
//scaled x and y cordinate
double x0 = mape(j, 0, W, MinX, MaxX);
double y0 = mape(i, 0, H, MinY, MaxY);
double x = 0.0f;
double y = 0.0f;
int iteration = 0;
double z = 0;
while (abs(z)<2.0f amp;amp; iteration < maxIteration)// amp;amp; iteration < maxIteration)
{
double xtemp = x * x - y * y x0;
y = 2 * x * y y0;
x = xtemp;
iteration ;
z = x * x y * y;
if (z > 10)//must be 10
break;
}
int b =mape(iteration, 0, maxIteration, 0, 255);
if (iteration == maxIteration)
b = 0;
im.setPixel(j, i, Color(b,b,0));
}
}
}
функции mape просто преобразуют число из одного диапазона в другой
Вот функция потока
void th(Imageamp; im)
{
float size = (float)im.getSize().x / num_th;
int x_min = 0, x_max = size, y_min = 0, y_max = im.getSize().y;
thread t[num_th];
for (size_t i = 0; i < num_th; i )
{
t[i] = thread(Mandelbrot, x_min, x_max, y_min, y_max, ref(im));
x_min = x_max;
x_max = size;
}
for (size_t i = 0; i<num_th; i )
{
t[i].join();
}
}
Основная функция выглядит следующим образом
int main()
{
Image img;
while(1)//here is while window.open()
{
th(img);
//here im drawing
}
}
Так что я не получаю никакого повышения производительности , но это становится еще медленнее , может ли кто-нибудь сказать мне, в чем проблема, что я делаю не так, это тоже случалось со мной раньше
Я задаю вопрос , что такое изображение, это класс из библиотеки SFML, не знаю, поможет ли это.
Комментарии:
1. петля внутри
main
бесконечна!. завершается ли эта программа?!! Этот код не будет компилироваться или он неполный.2. @assmo да , это делает условие для цикла, когда окно открыто и рисуется, но проблема не в этом.
3. Сделайте слишком много потоков, и вы замедлите работу системы, поскольку она борется за ядра. Ты это делаешь? Смурфик, если я знаю. У вас есть одновременный несинхронизированный доступ к
im
. Является ли это проблемой или нет, зависит от встроенных в нее умныхsetPixel
способностей . Так в чем же проблема? Смурфик, если я знаю.4. В вопросе отсутствует много деталей. Что такое
Image
? Как вы выполняете тайминги? Оптимизирована ли сборка? Вы также используете нестандартные функции, такие как массивы переменной длины.5. @G. M. это из библиотеки sfml
Ответ №1:
Ваш код неполон, чтобы ответить вам конкретно, но есть несколько подозрений:
- Создание потока имеет нетривиальные накладные расходы. Если объем работы, выполняемой потоком, недостаточно велик, накладные расходы на его запуск могут стоить больше, чем любые выгоды, которые вы получили бы благодаря параллелизму.
- Чрезмерная блокировка и раздоры. Это не похоже на проблему в вашем коде, так как вы, похоже, вообще не используете никаких блокировок. Будьте осторожны (хотя до тех пор, пока они не пишут по одним и тем же адресам, это должно быть правильно).
- Ложный общий доступ: Возможная проблема в вашем коде. Строки кэша, как правило, составляют 64 байта. Любая запись в любую часть строки кэша приводит к тому, что вся строка фиксируется в памяти. Если два потока просматривают одну и ту же строку кэша, и один из них записывает в нее, даже если все остальные потоки используют другую часть этой строки кэша, их копия будет признана недействительной и их придется повторно извлекать. Это может вызвать значительные проблемы, если несколько потоков работают с неперекрывающимися данными, которые совместно используют строку кэша, и приводят к этим ошибкам. Если они повторяются с одинаковой скоростью по одним и тем же данным, это может привести к повторению этой проблемы снова и снова. Эта проблема может быть значительной, и ее всегда стоит учитывать.
- расположение памяти, приводящее к разгрому вашего кэша. При прохождении через массив переход «поперек» может совпадать с фактическим расположением памяти, считывая одну полную строку кэша за другой, но сканирование «вертикально» касается одной части строки кэша, а затем переходит к соответствующей части другой строки кэша. Если это происходит во многих потоках, и у вас много памяти для обработки, это может означать, что ваш кэш значительно недоиспользуется. Просто нужно остерегаться, независимо от того, является ли ваша машина основной строкой или столбцом, и писать код, соответствующий ей, и избегать скачков в памяти.