2013-04-22 65 views
0

因此,我正在編寫一個程序來使用pthread來計算Mandelbrot集。
這是線程函數:
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(); 
} 

pthread_create之前和之後pthread_join設置一個對clock_t
Mandelbrot集的結果是正確的,但是,在計算時間總是相同的,儘管我增加線程的數量從1到8
由於"enter"被第二pthread_join之前同時打印出,我相信線程並行執行。
我想這個問題可能是partial_compute有線程安全函數,但是我找不到它。 (我嘗試用float而不是班級來表示複數)
我在這裏做了什麼錯誤嗎?感謝您的幫助。

更新:
對不完整的信息抱歉。
z.length()表示複數z的平方。
這是我如何分割任務。 x_lengthy_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()'做了什麼? – 2013-04-22 09:01:33

+2

你能告訴我們如何拆分集合以在線程之間進行計算,即哪個線程正在計算總集合的哪一部分? – ogni42 2013-04-22 09:01:46

+1

把代碼也啓動線程... – UmNyobe 2013-04-22 09:01:54

回答

1

我發現這個問題是clock() ......
clock()不能用來測量經過的時間,當您使用並行線程,
因此我發現gettimeofday(timeval, NULL)可以正常工作。

0

是的,Pthreads中的clock()存在問題。您可以使用clock_gettime()CLOCK_MONOTONIC選項來正確測量Pthread中的時間。您還需要鏈接到POSIX實時擴展(-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;