2012-01-13 94 views
4

我想在使用openMP的C++中迭代映射,但我得到了三條錯誤消息,說
我的循環的初始化,終止和增量具有不正確的形式,而我在使用openmp方面相當新,所以有什麼辦法解決這個問題,同時獲得與串口相同的結果?以下是我使用的代碼在迭代映射中使用openmp

map< int,string >::iterator datIt; 
#pragma omp parallel for 
for(datIt=dat.begin();datIt!=dat.end();datIt++) //construct the distance matrix 
{ 
............... 
} 

回答

3

很可能您的OpenMP實現與STL迭代器不兼容。雖然有一些changes to the standard to make OMP more compatible with the STL,我想你會發現你的實現不支持這種行爲。我遇到的大多數OpenMP實現至多是版本2.5,Microsoft C++是2.0。我知道唯一支持3.0的編譯器是Intel C++編譯器。

其他幾點,你應該使用std :: begin和std :: end。此外,您可能需要自行申報的循環不變爲私有,或有OpenMP的數字說出來,像這樣:

#pragma omp parallel for 
for(map< int,string >::iterator datIt = std::begin(dat); 
    datIt != std::end(dat); 
    datIt++) 
{ 
    //construct the distance matrix... 
} 

但是,如果沒有3.0的支持,這是毫無意義的。

+3

gcc自4.4版開始支持OpenMP 3.0,並且將在4.7版本中支持3.1,所以它大部分是在C++中被卡住的石器時代。除了openmp 3.0之外,只允許'random_access_iterators'作爲循環變量,但'map'只支持'bidrectional_iterators',所以這沒有幫助。爲什麼'std :: begin','std :: end'優先於成員函數,我沒有看到任何好處,因爲它除了調用成員函數之外什麼都不做。 – Grizzly 2012-01-25 22:14:59

+0

@Grizzly我不知道GCC OpenMP支持,謝謝你。而且您應該使用非成員begin(...)和end(...),因爲它們可以專門用於支持缺少開始和結束成員函數的容器。這就把重點放在泛型編程上,這正是C++所擅長的。如果你不願意接受我的話,可以參考[Herb Sutter's](http://herbsutter.com/elements-of-modern-c-style/)。 – 2012-01-25 22:34:09

+0

考慮到代碼中明確提到了迭代器的類型,並沒有使其更通用。除了'std :: begin'通常不能專門用於缺少成員函數的容器,因爲你不能部分地專門化函數模板,並且不允許在'std'中添加重載。爲了使它更通用,你需要使用一個非限定版本('begin()','end()'),加上'using namespace std;'或'using std :: begin;使用std :: end;',因爲我會假設容器更有可能具有成員函數,那麼獨立的命名空間版本 – Grizzly 2012-01-25 22:41:46

-1

如果有用,請嘗試這種方法。

#pragma omp parallel for shared(dat) private(datIt) 
for(map< int,string >::iterator datIt=dat.begin();datIt!=dat.end();datIt++) 
{ 
............... 
} 
0

OpenMP的3.0現已在gcc和英特爾編譯器任務指令,允許線程委派任務線程

的拉從啓發:this responsethis course,我寫這些樣的代碼對我來說,做工精細:

map< int,string >::iterator datIt; 
... 
#pragma omp parallel for 
#pragma omp single nowait 
{ 
    for(datIt=dat.begin();datIt!=dat.end();datIt++) //construct the distance matrix 
    { 
    #pragma omp task firstprivate(datIt) 
    { 
    ............... 
    } 
    } 
} 

一個任務(指令)整個地圖上環,並把每一項工作永遠做y元素映射到任務中。其他OMP線程處理任務仍然處於這種拉動狀態。其他OMP任務不需要等待結束循環開始任務處理(nowait)。每個任務都有一個指向處理映射的元素的指針(firstprivate(datit))。

約束條件:每個任務必須是獨立的,並且映射在結束之前不得更改。

1

也可以通過使用基於std::advance的蝙蝠圈的簡單索引來達到特定地圖元素。 OpenMP 2.0非常適合支持基於循環的索引。

#pragma omp parallel for 
    for(int i = 0; i < dat.size(); i++) { 
     auto datIt = dat.begin(); 
     advance(datIt, i); 
     //construct the distance matrix using iterator datIt 
    } 

在每個線程迭代datIt將指向一個地圖信息並可以被用於在其上執行操作。