2017-01-29 27 views
0

Я работаю над проектом, чтобы переписать последовательный алгоритм C-кода для создания набора mandelbrot в параллельном с использованием pthreads. Я поднялся на стену, так сказать, потому что моя версия просто выводит более или менее черную картинку (и ничего, к чему приводит исходная программа), и я не могу понять, где я ошибаюсь. Проще говоря, я мог бы использовать вторую пару глаз на этом.Мандельброт, используя Pthreads, перешагнув массив

Вот последовательный фрагмент кода, который имеет значение:

void mandelbrot(float width, float height, unsigned int *pixmap) 
{ 
int i, j; 
float xmin = -1.6f; 
float xmax = 1.6f; 
float ymin = -1.6f; 
float ymax = 1.6f; 
for (i = 0; i < height; i++) { 
    for (j = 0; j < width; j++) { 
     float b = xmin + j * (xmax - xmin)/width; 
     float a = ymin + i * (ymax - ymin)/height; 
     float sx = 0.0f; 
     float sy = 0.0f; 
     int ii = 0; 
     while (sx + sy <= 64.0f) { 
      float xn = sx * sx - sy * sy + b; 
      float yn = 2 * sx * sy + a; 
      sx = xn; 
      sy = yn; 
      ii++; 
      if (ii == 1500) { 
       break; 
      } 
     } 
     if (ii == 1500) { 
      pixmap[j+i*(int)width] = 0; 
     } 
     else { 
      int c = (int)((ii/32.0f) * 256.0f); 
      pixmap[j + i *(int)width] = pal[c%256]; 
     } 
    } 
} 


} 

Вот моя последовательная версия кода:

void* Mandel(void* threadId) { 
    int x = *(int*)threadId; 
    float xmin = -1.6f; 
    float xmax = 1.6f; 
    float ymin = -1.6f; 
    float ymax = 1.6f; 

    float b = xmin + x * (xmax - xmin)/WIDTH; 
    for (int y = 0; y < 1024; y++) 
    { 
     float a = ymin + y * (ymax - ymin)/WIDTH; 
     float sx = 0.0f; 
     float sy = 0.0f; 
     int ii = 0; 
     while (sx + sy <= 64.0f) { 
      float xn = sx * sx - sy * sy + b; 
      float yn = 2 * sx * sy + a; 
      sx = xn; 
      sy = yn; 
      ii++; 
      if (ii == 1500) { 
       break; 
      } 
     } 
     if (ii == 1500) { 
      pixmap[x+y*(int)WIDTH] = 0; 
     } 
     else { 
      int c = (int)((ii/32.0f) * 256.0f); 
      pixmap[x + y *(int)WIDTH] = pal[c%256]; 
     } 
    } 
} 

Объяснение моего мыслительного процесса: создать 1024 потоков в основной и затем вызовите функцию выше с каждым потоком. Они должны иметь столбец каждый (поскольку x является константой от 0 до 1023, а значение y изменяется от 0 до 1023 в пределах функции). Как вы можете видеть, большая часть математического мяса в самой функции одинакова как в последовательных, так и в моих параллельных версиях кода. Из-за этого, я думаю, проблема связана с тем, как я перешагиваю массив, но я не вижу проблемы своими глазами. Независимо от того, значение, которое в конечном итоге получает бит, используется для вычисления c, которое, в свою очередь, используется для определения значения цвета, которое должно быть сохранено в соответствующей позиции в pixmap. (pal - это просто большой массив, заполненный цветами).

Эта функция является единственной частью кода, которую я действительно затронул в любой степени. Единственная разница в основной функции заключается в том, что я создал в ней потоки с инструкцией для выполнения функции Mandel.

Я предполагаю, что любой желающий помочь захочет получить дополнительную информацию, и, пожалуйста, сообщите мне о любых улучшениях этого сообщения в случае, если я разместил слишком мало информации.

+0

Как вы проходите в threadId при запуске потоков? Поскольку вы, кажется, используете указатель, вам нужно сохранить фактическое значение после вызова pthread_create(). Если вы, например, используете одну и ту же переменную и просто увеличиваете ее после создания каждого потока, отдельные потоки, вероятно, не получат правильные значения, так как местоположение, на которое указывает threadId, будет изменено до того, как значение будет прочитано в ... – sonicwave

+0

Я сам решил, я отправлю ему ответ на обновление. –

+0

Но да, вы нанесли ему гвоздь прямо на голову: P –

ответ

0

Я нашел ответ вскоре после публикации этого кода. Дурак я.

Anywho, проблема не заключалась в массиве внутри функции, но на самом деле, как я создал потоки.

Вот как это выглядело в основном, когда возникла проблема:

for(int k = 0; k < 1024; k++) { 
    pthread_create(&threads[k], NULL, (void*)Mandel, (void*) k); 
} 

Проблема с делать это таким образом, что цикл продолжается, изменив значение к для следующего потока, а это означает, что последний поток, который мы только что создали, внезапно получил простую ценность для k. Эта задача была решено с помощью Int массива, который сохраняет значения к, как мы проходим через каждое значение к и создать каждую нить, как показано ниже:

int id[1024]; 
for(int k = 0; k < 1024; k++) { 
    pthread_create(&threads[k], NULL, (void*)Mandel, (void*)(id+k)); 
} 

Я хотел бы указать к сообщению в следующей ссылке, за помощь в ответе на эту проблему: Pass integer value through pthread_create

Просто идет, чтобы показать, что вы можете часто находить ответы, которые вы ищете, если вы ищете достаточно долго, в течение большей части времени.

 Смежные вопросы

  • Нет связанных вопросов^_^