2011-10-06 4 views
0

특정 코드 단편에서 OpenMP를 사용하려고합니다. 스 니펫에 개편이 필요한지 확실하지 않은 경우 순차적 구현을 ​​위해 너무 엄격하게 설정되어있을 수 있습니다. 어쨌든 여기에 내가 병렬화 노력하고있어 (사이비) 코드입니다 : 이것은 순차적 인 의미에서 (몇 시간 동안 그것을 쳐다보고 후) 완전한 의미가병렬 for 루프에 대한 C++ OpenMP 지시문?

#pragma omp parallel for private(id, local_info, current_local_cell_id, local_subdomain_size) shared(cells, current_global_cell_id, global_id) 
for(id = 0; id < grid_size; ++id) { 
    local_info = cells.get_local_subdomain_info(id); 
    local_subdomain_size = local_info.size(); 
    ...do other stuff... 
    do { 
     current_local_cell_id = cells.get_subdomain_cell_id(id); 
     global_id.set(id, current_global_cell_id + current_local_cell_id); 
    } while(id < local_subdomain_size && ++id); 
    current_global_cell_id += local_subdomain_size; 
} 

, 그것은 필요가도 어느 의미 할 수 있습니다 OpenMP 용으로 다시 작성하십시오. 내 관심사는 current_local_cell_id 및 local_subdomain_size는 private이지만 current_global_cell_id 및 global_id는 공유됩니다.

따라서 문 current_global_cell_id + = local_subdomain_size은 내부 루프 후 :

do { 
    ... 
} while(...) 
current_global_cell_id += local_subdomain_size; 

는 OpenMP를 설정에서 오류가 발생할 수있다, 나는 생각한다. OpenMP 전문가가 코드에 최소한의 변경을 가할 수 있지만 여전히 for 루프와 같은 유형의 OpenMP를 사용할 수있는 특수 OMP 지시문에 대한 몇 가지 지침을 제공 할 수 있다면 크게 감사하겠습니다.

답변

2

코드를 잘 모르겠습니다. 그러나, 나는 당신이 정말로 어떤 종류의 평행 축적을 원한다고 생각합니다. 방금 exactly 같은 않는, std::accumulate__gnu_parallel::accumulate 드롭 인 교체를 사용할 수있는 gcc를 사용할 때

당신은, 관련 메모에

size_t total = 0; 
#pragma omp parallel for shared(total) reduction (+:total) 
for (int i=0; i<MAXITEMS; i++) 
{ 
     total += getvalue(i); // TODO replace with your logic 
} 

// total has been 'magically' combined by OMP 

같은 패턴을 사용할 수 있습니다. 당신도 가능하면 std 알고리즘의 모든 사용이 자동으로 parallellized 것 -D_GLIBCXX_PARALLEL로 컴파일 할 수 있습니다 Chapter 18. Parallel Mode

size_t total = __gnu_parallel::accumulate(c.begin(), c.end(), 0, &myvalue_accum); 

참조하십시오. 자신이하는 일을 모르는 경우 사용하지 마십시오! 자주 성능이 저하되고 예기치 않은 병렬 처리로 인해 버그가 발생할 가능성이 있습니다.

+0

GNU 병렬 모드에서 힌트가 추가되었습니다. – sehe

+0

흥미로운 의견입니다. 이 정보를 공유해 주셔서 감사합니다. –

1

루프 내부의 ID가 바르게 변경되지 않았습니다. 루프 단계는 예측 가능한 id 값을 생성하지 않으므로 다른 스레드에 루프를 전달할 방법이 없습니다.

왜 그 동안 id를 사용하고 있습니까?

+0

한숨! 당신이 옳을 수도 있습니다. 나는 그것을 바꾸지 않기를 바랬다. 하지만 current_global_cell_id를 private로 설정해도 여전히 작동 할 수 있다고 생각합니다. –

+0

그때는 정말 글로벌하지 않습니다 ;-) 그 변수는 무엇을 위해 사용됩니까? 루프에서 id가 변경되지 않을 때까지 작동하지 않습니다. – crazyjul