2015-05-17 99 views
3

我嘗試計算並行簡單代碼的加速。這是一個簡單的循環。首先,我用C++中的open-mp來並行化它。然後我想查找每個線程的執行時間,我使用最大線程時間作爲並行執行時間。我用不同的線程數重複它,但時間更糟!你可以幫幫我嗎?爲什麼在我的openmp代碼中增加執行時間?

#include "stdafx.h" 
#include "omp.h" 
#include "conio.h" 
double diftime[64]; 
int a,i,threadnum; 
int main() 
{ 
threadnum=2; 
omp_set_nested(1); 
omp_set_dynamic(0); 
#pragma omp parallel num_threads(threadnum) 
{ 
    double start_time,end_time; 
    int id = omp_get_thread_num(); 
    start_time=omp_get_wtime(); 
    #pragma omp for nowait schedule(static) 
    for (i=0;i<2000000;i++){a++;} 
    end_time=omp_get_wtime(); 
    diftime[id]=diftime[id]+(end_time-start_time);  
    printf("thread[%d] = %.32g\n",id,end_time-start_time); 
} 
getch(); 
return 0; 
} 

回答

3

的原因是,你的循環操作就是這麼簡單編譯器替換的a循環之後的結果循環。看看這個例子:

#include <stdio.h> 

int main() 
{ 
    size_t i; 
    unsigned a = 0; 
    for (i = 0; i < (1UL << 20); i++) // the loop should run 1048576 times 
     a++; 
    printf("%ud\n", a); 
    return 0; 
} 

但是,當我們通過gcc -O2 -S test.c查看生成的指示,我們發現

_main: 
LFB20: 
    subq $8, %rsp 
LCFI0: 
    movl $1048576, %esi # the loop is replaced by a's value! 
    xorl %eax, %eax 
    leaq LC0(%rip), %rdi 
    call _printf 
    xorl %eax, %eax 
    addq $8, %rsp 
LCFI1: 
    ret 

那麼,爲什麼你測量的時間上升的原因是,它需要更多的時間生成和處理更多的線程(這些線程沒有做任何事情)。


如果要強制編譯器創建一個循環,你應該使環路volatile變量,像:

#include <stdio.h> 

#include <omp.h> 

double diftime[64]; 
int main() 
{ 
    int i; 
    unsigned a = 0; 
#pragma omp parallel 
    { 
     double start_time, end_time; 
     int id = omp_get_thread_num(); 
     start_time = omp_get_wtime(); 
     volatile int b = 0; // ############################# 
#pragma omp for nowait schedule(static) 
     for (i = 0; i < (1UL << 20); i++) 
     b++; 
     end_time = omp_get_wtime(); 
     diftime[id] = diftime[id] + (end_time - start_time); 
     printf("thread[%d] = %.32g\n", id, end_time - start_time); 
// ensure only one thread at a time executes the next line 
#pragma omp critical 
     a += b; 
    } 
    printf("a = %d\n", a); 
    return 0; 
} 
相關問題