2017-11-25 7 views
0

저는 OpenMP를 처음 사용하고 있으며 병렬 처리하려고하는 몬테카를로 코드가 있습니다. OpenMP - for 루프의 스레드 생성 및 종료시 오버 헤드

나는이 a를 new_value() 함수를 호출 순차적으로 실행되어야합니다 - 루프 :

void new_value() 
{ 
#pragma omp parallel default(shared) 
{ 
    int thread_rank = omp_get_thread_num(); 

#pragma omp for schedule(static) 
    for(int i = 0; i < N; i++) 
     arr[i] = update(thread_rank); 
} 
} 

작동하지만이 :

for(int i = 0; i < MAX_VAL; i++) 
    new_value(); 

이 기능은 각 통화에 병렬 영역이 열립니다 스레드의 생성 및 종결과 관련하여 상당한 양의 오버 헤드가 발생합니다. 루프를 병렬 처리하지 않고 루프를 시작하기 전에 누군가 스레드를 생성하고 (thread_rank에 도달하는) 방법을 알고 있는지 궁금합니다.

같은 일을 묻는 몇 가지 질문이 있습니다하지만 그들은 그 예는 다음을 포함 하나 틀리거나 답이 있습니다 :

This question유사한 일을 묻는하고 대답에 #pragma omp single를 사용하여 다음 병렬 영역을 작성하고 제안 가장 바깥 쪽 루프가 아니라 'Joe C'가 답변의 코멘트에서 말한 것처럼 이것이 작동하지 않습니다. 프로그램이 멈췄는지 확인할 수 있습니다.

This question정확한 같은 일을 요청하지만, (선택 해제) 대답은 단지 인 루프 4000 * num_threads를 실행하는 가장 바깥 쪽 루프를 parallelise하는 것도 무엇 아스 커 원하는도 내가 원하는.

답변

0

두 번째 질문에 대한 답변이 실제로 정확합니다.

#pragma omp parallel 
for(int i = 0; i < MAX_VAL; i++) 
    new_value(); 

void new_value() 
{ 
    int thread_rank = omp_get_thread_num(); 

#pragma omp for schedule(static) 
    for(int i = 0; i < N; i++) 
     arr[i] = update(thread_rank); 
} 

정확하고 원하는 것입니다. 그것은 당신의 질문에있는 코드와 동일한 의미를 가지고 있습니다. 차이점은 단 하나의 병렬 영역이 있고 루프 변수 i이 전체 팀에 의해 계산된다는 것입니다. 외부 루프는 이 아니며은 작업 공유 방식 (omp parallel for)으로 병렬화되어 있지 않습니다.

이 코드를 실행하면 num_threads 스레드는 루프 헤더를 new_value 번 실행하고 omp for은 모두 i == 0에 도달합니다. 그들은 내부 루프의 작업을 공유 할 것입니다. 그런 다음 그들은 모두가 암시 적 장벽에서 루프를 완료 할 때까지 기다릴 것이고, 자신의 i을 증가시키고 반복 할 것입니다 ... 이전과 같이 내부 루프와 관련하여 동일한 동작이며 스레드 관리 오버 헤드가 줄어들 었음이 분명합니다.

+0

대단한 설명에 감사드립니다. 나는 약간의 후속 질문을 가지고있다. (만약 마음에 들지 않는다면) : 어떻게하면 각 스레드가 원래 생각했던 것처럼 for 루프를 실행시킬 수 있을까? 즉,'num_threads * MAX_VAL' 번? – BodneyC

+0

실제로 실제로'num_threads * MAX_VAL'이 실행되지만 작업 공유로 인해 내부 루프 반복은'MAX_VAL * N '회 실행됩니다. 그러므로 내부의'omp for'를 제거하면 내부 루프 본문이'num_threads * MAX_VAL * N' 번 실행됩니다. – Zulan

+0

스팟이 켜져 있습니다. 다시 한번 감사드립니다. – BodneyC