2016-07-29 63 views
0

我對openmp沒有太多經驗。OpenMP for loop和指針

是否可以通過使用for循環而不是索引而使下面的代碼更快?

有沒有辦法讓下面的代碼更快?

該代碼將數組乘以常量。

謝謝。

代碼:

#include <iostream> 
#include <stdlib.h> 
#include <stdint.h> 
#include <vector> 
using namespace std; 
int main(void){ 
    size_t dim0, dim1; 
    dim0 = 100; 
    dim1 = 200; 
    std::vector<float> vec; 
    vec.resize(dim0*dim1); 
    float scalar = 0.9; 
    size_t size_sq = dim0*dim1; 
    #pragma omp parallel 
    {  
     #pragma omp for 
     for(size_t i = 0; i < size_sq; ++i){ 
      vec[i] *= scalar; 
     } 
    } 
} 

串行指針循環

float* ptr_start = vec.data(); 
float* ptr_end = ptr_start + dim0*dim1; 
float* ptr_now; 
for(ptr_now = ptr_start; ptr_now != ptr_end; ++ptr_now){ 
    *(ptr_now) *= scalar; 
} 
+0

循環中只有20,000個值,並且CPU同步也有一些開銷。你有沒有測量循環有多快,沒有OMP?你能分享這些結果嗎? –

+0

實際的數組比這個大得多。我也想知道如果我做了一些傷害性能的東西,因爲我也會在其他地方使用openmp。 – rxu

+0

真正生成的代碼可能與您寫的代碼有所不同。您是否通過所有優化反彙編了發佈程序? P.S .:你的OpenMP允許你使用'size_t'作爲索引類型嗎? – ilotXXI

回答

1

串行指針循環應該是這樣

size_t size_sq = vec.size(); 
float * ptr = vec.data(); 
#pragma omp parallel 
{  
    #pragma omp for 
    for(size_t i = 0; i < size_sq; i++){ 
     ptr[i] *= scalar; 
    } 
} 

ptr將所有線程一樣的,所以沒有問題存在。

作爲解釋,Data sharing attribute clauses (wikipedia)

共享:並行區域內的數據是共享的,這意味着 可見和可訪問通過同時所有線程。默認情況下,工作共享區域中的所有 變量共享,除了循環 迭代計數器。

private:並行區域內的數據對每個線程都是私有的, 這意味着每個線程都有本地副本並將其用作 臨時變量。私有變量未初始化,並且 值不保留在並行區域之外使用。默認情況下,OpenMP循環結構中的循環迭代計數器爲 私有。

在這種情況下,i是私人的,ptr共享。

+0

謝謝。我不知道同一個地址會在所有線程中引用同一塊內存。 – rxu

+0

如果這是成功並行化的,默認的靜態調度會給每個線程幾乎相等的大小塊。 – tim18

+0

線程在同一進程中共享除堆棧外的地址空間:http://stackoverflow.com/questions/1762418/process-vs-thread – rxu