2011年6月30日 星期四

讓程式更快 - 多核心處理器2

上一個章節的 code 只是個浪費時間的迴圈
為了符合現狀 現在要實際來做一些運算

宣告個 global 變數
加總 並印出來




#include <omp.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <tchar.h>

int total = 0;

void Test( int n )
{
 for( int i = 0; i < 40000; ++ i )
 {
  total++;
 }
 printf( "%d, ", n );
}

int main(int argc, char* argv[])
{
    clock_t start_time, end_time;
    float total_time = 0;

    start_time = clock(); /* mircosecond */

    #pragma omp parallel for
    for( int i = 0; i < 10; ++ i )
        Test( i );

    printf("total: %d\n", total);

    end_time = clock();
    total_time = (float)(end_time - start_time)/CLOCKS_PER_SEC;

    printf("Time : %f sec \n", total_time);

}


出來的結果
5, 0, 1, 6, 2, 7, 8, 9, 3, 4, total: 316528
Time : 0.015000 sec
請按任意鍵繼續 . . .

5, 0, 6, 1, 7, 2, 8, 3, 9, 4, total: 271579
Time : 0.000000 sec
請按任意鍵繼續 . . .

竟然每次的 total 值都不一樣
這就是所謂的多執行緒中的 race condition

要把程式可以正常必須對變數做同步
第一是在 total++; 前面加上 #pragma omp atomic
很好很強大很簡單 但是當你把 Test() 迴圈加到 4000000
會發現喵的速度比不用多執行緒還慢
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, total: 40000000
Time : 1.281000 sec
請按任意鍵繼續 . . .

0, 5, 1, 6, 7, 2, 3, 8, 9, 4, total: 40000000
Time : 2.904000 sec
請按任意鍵繼續 . . .

應該看的出來哪種是有用 哪種是沒用吧 (看執行順序)
原因出在花費太多時間在同步了

還有另外一種寫法 使用 reduction
#pragma omp parallel for reduction( +:total)
但是我們運算的 total++; 是在 sub-function 中 這種無法同步化
所以兩種改法 一種是改成


    #pragma omp parallel for reduction( +:total)
    for (int i=0;i<10;i++)
    {
        for (int j=0;j<4000000;j++)
        {
            total++;
        }
    }


另一種改成把 total call by reference 過去 (call by address 也可以)


void Test( int n , int &sum)
{
 for( int i = 0; i < 4000000; ++ i )
 {
  sum++;
 }
 printf( "%d, ", n );
}
    #pragma omp parallel for reduction( +:total)
    for (int i=0;i<10;i++)
    {
        Test( i, total);
    }



OK 完成
應該可以符合大部分的應用了

出來的結果
5, 0, 6, 1, 2, 7, 3, 4, 8, 9, total: 40000000
Time : 0.078000 sec
請按任意鍵繼續 . . .

我一直以為要再迴圈最後面補上 #pragma omp barrier
也就是 printf("total: %d\n", total); 之前
等待所有 thread 結束後才繼續執行
但是看起來不用 也不清楚為什麼 XD

沒有留言:

張貼留言

開放匿名留言 請大家注意網路禮儀