2010-03-25 5 views
18

opendmp를 사용하여 루프를 std :: set을 통해 다중 쓰려고합니다. 나는 다음과 같은 코드를 작성할 때 -openmp에서 std 컨테이너를 통한 반복

#pragma omp parallel for 
    for (std::set<A>::const_iterator i = s.begin(); i != s.end(); ++i) { 
      const A a = *i; 
      operate(a); 
    } 

을이 오류를 얻을 :

error: invalid type for iteration variable 'i' 
error: invalid controlling predicate 
error: invalid increment expression. 

은 OpenMP의를 사용하여 표준 컨테이너를 반복하는 또 다른, 올바른 방법이 있습니까? int i을 사용하고 루프 본문에 0에서 s.size()까지 반복하고 반복자 또는 operator[]을 반복 사용할 수 있지만이 방법은 훨씬 덜 깨끗해 보입니다.

+1

어떤 컴파일러입니까? GCC는'std :: for_each'의 병렬 구현 (http://gcc.gnu.org/onlinedocs/libstdc++/manual/parallel_mode.html)을 가지고 있습니다. 어쩌면 그 소스도 볼 수 있을까요? http://algo2.iti.kit.edu/singler/mcstl/을 참조하십시오. – stephan

답변

21

stl 반복자에 대한 루프 병렬화는 OpenMP 3.0 이후 및 임의 액세스 반복자 (예 : vectordeque)에서만 작동합니다. 당신이 뭔가를 할 수 있어야한다 : 전체 시퀀스에 각 스레드의 반복은 (하지만 그 중 일부에 operate를 실행)하지만 때문에

#pragma omp parallel { 
    for (std::set<A>::const_iterator i = s.begin(); i != s.end(); ++i) { 
     #pragma omp single nowait { 
     operate(*i); 
     } 
    } 
} 

오버 헤드가 매우 큽니다. int i을 사용하는 방법이 더 효율적입니다.

대안으로 GCC의 병렬 구현 인 std::for_each을 살펴보십시오. 내 의견보기.

편집 : 대부분 C++ (17)의 일부가 될 것입니다 STL Parallism TS는 표준 컨테이너 반복의 미래에 좋은 옵션이 될 수 있습니다.

+0

감사합니다. MCSTL은 내가 필요로하는 것입니다. –

+0

'std :: set'에는'operator []'가없고 msvc는 openmp 2.0 만 지원합니다 :/ – quimnuss

+1

@quimnuss : msvc에 대한 [Parallel STL] (https://parallelstl.codeplex.com/)이 도움이 될 수 있습니다 . [Parallelism TS] (https://isocpp.org/files/papers/P0024R2.html)는 C++ 17의 일부가 될 가능성이 높기 때문에 장래성이 보장되어야합니다 (하지만 여전히 버그가있을 수 있으며 기능이 아닐 수도 있습니다 완료, 나는 MS 구현을 너무 가깝게 따라 가지 않았다). – stephan