2010-09-23 164 views
19

OpenMP本身支持減少表示數組的變量嗎?是否有可能使用openmp來減少數組?

這會工作像下面這樣...

float* a = (float*) calloc(4*sizeof(float)); 
omp_set_num_threads(13); 
#pragma omp parallel reduction(+:a) 
for(i=0;i<4;i++){ 
    a[i] += 1; // Thread-local copy of a incremented by something interesting 
} 
// a now contains [13 13 13 13] 

理想的情況下,就對OMP並行一個類似的東西,如果你有一個大的線程數量足以爲它是有道理的,積累將通過二叉樹發生。

+7

只有在fortran – Anycorn 2010-09-23 03:41:10

+1

可能你可以解釋更多你想要做的事。提供串行代碼可能有幫助。 – FFox 2010-09-27 05:49:48

+0

挖掘更多,聽起來像「只有在fortran」是答案。我最終只是在循環之外分配一個大的本地副本數組,讓線程在for循環中累積到自己的副本,然後在for循環之後積累到全局數組中,仍然在並行區域內部,在關鍵部分。 – 2010-09-27 19:52:35

回答

3

只有在OpenMP 3.0的Fortran中,可能只有某些編譯器。

參見最後一個例子(實施例3):

http://wikis.sun.com/display/openmp/Fortran+Allocatable+Arrays

+3

現在可以使用OpenMP 4.5了;請看下面陳江的回答。基本上,您必須指定_array sections_(請參見OpenMP 4.5規範的第2.4節,第44頁)。 你的#pragma規範看起來是這樣的: '#pragma omp parallel reduction(+:a [:4])' 但是,要小心這個,但你必須認識到每個線程將分配它自己的版本數組部分;如果在具有多線程的大型數組上執行此操作,則可能會使內存需要爆炸。 – 2016-06-02 14:55:05

1

OpenMP無法對數組或結構類型變量執行減少操作(請參閱restrictions)。

您也可能想要閱讀privateshared條款。 private聲明一個變量對每個線程都是私有的,其中shared聲明一個要在所有線程之間共享的變量。我還發現這個question的答案在OpenMP和陣列方面非常有用。

3

對於C和C++,現在可以使用OpenMP 4.5進行數組縮減。這裏有一個例子:

#include <iostream> 

int main() 
{ 

    int myArray[6] = {}; 

    #pragma omp parallel for reduction(+:myArray[:6]) 
    for (int i=0; i<50; ++i) 
    { 
    double a = 2.0; // Or something non-trivial justifying the parallelism... 
    for (int n = 0; n<6; ++n) 
    { 
     myArray[n] += a; 
    } 
    } 
    // Print the array elements to see them summed 
    for (int n = 0; n<6; ++n) 
    { 
    std::cout << myArray[n] << " " << std::endl; 
    } 
} 

輸出:

100 
100 
100 
100 
100 
100 

我用GCC編譯6.2本。您可以在此處看到哪些常見編譯器版本支持OpenMP 4.5功能:http://www.openmp.org/resources/openmp-compilers/

請注意,雖然這是方便的語法,但它可能會爲每個線程創建每個陣列部分的副本,從而調用大量開銷。

0

從OpenMP 4.5開始,OpenMP可以執行此操作,並且GCC 6.3(可能更低)支持它。一個例子程序如下所示:

#include <vector> 
#include <iostream> 

int main(){ 
    std::vector<int> vec; 

    #pragma omp declare reduction (merge : std::vector<int> : omp_out.insert(omp_out.end(), omp_in.begin(), omp_in.end())) 

    #pragma omp parallel for default(none) schedule(static) reduction(merge: vec) 
    for(int i=0;i<100;i++) 
    vec.push_back(i); 

    for(const auto x: vec) 
    std::cout<<x<<"\n"; 

    return 0; 
} 

注意omp_outomp_in是特殊變量,而且declare reduction的類型必須您計劃,以減少對向量相匹配。