2013-04-22 3 views
0

Итак, я пишу программу для вычисления набора Мандельброта с использованием pthread.
Это функция потока:
Набор Mandelbrot не ускоряется с использованием pthread

void *partial_compute(void *arg) { 
    cout << "enter" << flush; 
    Range *range = (Range*)arg; 
    Comp z, c; 
    for (int i = range->begin; i <= range->end; i++) { 
     for (int j = 0; j < y_length; j++) { 
      z.set(0.0, 0.0); 
      c.set(x_start + (x_end - x_start) * i/x_length, y_start + (y_end - y_start) * j/y_length); 
      int k; 
      for (k = 0; k < 256; k++) { 
       z = z.next(c); 
       if (z.length() >= 4.0) { 
        break; 
       } 
      } 
      *(canvas + i * y_length + j) = k; 
     } 
    } 
    pthread_exit(NULL); 
} 


Какого Comp является классом комплексного числа, а z.next означает вычисление следующего Мандельброт итерации.

Comp Comp::next(Comp c) { 
    Comp n(next_real(c), next_imag(c)); 
    return n; 
} 
float Comp::next_real(Comp c) { 
    return _real * _real - _imag * _imag + c.real(); 
} 
float Comp::next_imag(Comp c) { 
    return 2 * _real * _imag + c.imag(); 
} 

Я поставил пару clock_t перед тем pthread_create и после pthread_join.
Результат набора Мандельброта правильный, однако время вычислений всегда одинаковое, несмотря на то, что я увеличил количество потоков от 1 до 8.
Поскольку "enter" были распечатаны за один раз за секунду до pthread_join, I что потоки выполнялись параллельно.
Я думаю, проблема может заключаться в том, что существует функция потокобезопасности в partial_compute, но я не могу ее найти. (Я пытаюсь представить комплексное число на float вместо класса)
Есть ли какая-то ошибка, которую я здесь сделал? Спасибо за помощь.

Обновление:
Извините за неполную информацию.
z.length() означает квадрат комплексного числа z.
Вот как я разделил задачу. x_length и y_length означает ширину и высоту экрана.
Я разделил экран на n по ширине и отправил диапазон в поток для вычисления.

int partial_length = x_length/num_threads; 
for (int i = 0; i < num_threads; i++) { 
    range[i].begin = i * partial_length; 
    range[i].end = range[i].begin + partial_length - 1; 
    pthread_create(&threads[i], NULL, partial_compute, (void *)&range[i]); 
} 
// wait all the threads finished 
for (int i = 0; i < num_threads; i++) { 
    pthread_join(threads[i], NULL); 
} 
+1

Что процессор (сколько ядер)? Что делает 'z.length()' do? –

+2

Можете ли вы показать нам, как вы разделили набор для вычисления между потоками, то есть какой поток вычисляет, какая часть общего набора? – ogni42

+1

Положите код, который также запускает потоки ... – UmNyobe

ответ

1

Я нашел проблема заключается в clock() ......
clock() не может быть использован для измерения истекшего времени, когда вы используете PTHREAD,
поэтому я нашел gettimeofday(timeval, NULL) может работать правильно.

0

Да, есть проблема с clock() в Pthreads. Вы можете использовать clock_gettime() с опцией CLOCK_MONOTONIC, чтобы правильно измерить время в Pthreads. Для этого вам также потребуется связать с POSIX Realtime расширениями (-lrt).

Вот примеры:

struct timespec begin, end; 
double elapsed; 

clock_gettime(CLOCK_MONOTONIC, &begin); 

// spawn threads to do work here 

clock_gettime(CLOCK_MONOTONIC, &end); 

elapsed = end.tv_sec - begin.tv_sec; 
elapsed += (end.tv_nsec - begin.tv_nsec)/1000000000.0;