2014-04-08 2 views
2

std :: map을 스캔하는 for-loop를 병렬 처리하려고합니다. 아래는 내 장난감 프로그램입니다 :OpenMP 맵을 이용한 루프 병렬화

#include <iostream> 
#include <cstdio> 
#include <map> 
#include <string> 
#include <cassert> 
#include <omp.h> 

#define NUM 100000 

using namespace std; 

int main() 
{ 
    omp_set_num_threads(16); 
    int realThreads = 0; 
    string arr[] = {"0", "1", "2"}; 
    std::map<int, string> myMap; 
    for(int i=0; i<NUM; ++i) 
    myMap[i] = arr[i % 3]; 

    string is[NUM]; 

    #pragma omp parallel for 
    for(map<int, string>::iterator it = myMap.begin(); it != myMap.end(); it++) 
    { 
    is[it->first] = it->second; 
    if(omp_get_thread_num() == 0) 
     realThreads = omp_get_num_threads(); 
    } 
    printf("First for-loop with %d threads\n", realThreads); 

    realThreads = 0; 
    #pragma omp parallel for 
    for(int i=0; i<NUM; ++i) 
    { 
    assert(is[i] == arr[i % 3]); 
    if(omp_get_thread_num() == 0) 
     realThreads = omp_get_num_threads(); 
    } 
    printf("Second for-loop with %d threads\n", realThreads); 
    return 0; 
} 

컴파일 명령 :

icc -fopenmp foo.cpp 

위의 코드 블록의 출력은 다음과 같습니다

First for-loop with 1 threads 
Second for-loop with 16 threads 

왜 내가 처음 for-을 병렬화 할 수없는입니다 고리?

+0

성공적으로 병렬화했는지 여부를 어떻게 결정하고 있습니까? – merlin2011

+0

'std :: map'은 스레드로부터 안전하지 않다고 생각하지 않으므로 배열로 먼저 변환하지 않고 동시에 루프 할 수있는 방법을 생각할 수 없습니다. –

+0

@ merlin2011 - 출력은 내부에있는 omp_get_num_threads()에서 가져옵니다. for-blocks. – Keval

답변

2

std::map은 임의 액세스 반복기를 제공하지 않으며 일반적인 양방향 반복기 만 제공합니다. OpenMP에서는 병렬 루프의 반복기가 임의 액세스 유형이어야합니다. 반복자의 다른 종류의 명시 적 작업을 대신 사용해야합니다

#pragma omp parallel 
{ 
    #pragma omp master 
    realThreads = omp_get_num_threads(); 

    #pragma omp single 
    for(map<int, string>::iterator it = myMap.begin(); it != myMap.end(); it++) 
    { 
    #pragma omp task 
    is[it->first] = it->second; 
    } 
} 

주를 별도의 작업이지도의 각 구성원에 대해 생성되는 경우. 태스크 본문은 계산 상으로는 간단하기 때문에 OpenMP 오버 헤드는 특정 경우에 상대적으로 높습니다.