2011-01-23 1 views
3

그래서 여기에 코드입니다 : 세드릭 의 OpenMP 스레드 "불순종"OMP 장벽

#pragma omp parallel private (myId) 
{ 
    set_affinity(); 

    myId = omp_get_thread_num(); 

    if (myId<myConstant) 
    { 
    #pragma omp for schedule(static,1) 
    for(count = 0; count < AnotherConstant; count++) 
     { 
     //Do stuff, everything runs as it should 
     } 
    } 

#pragma omp barrier //all threads wait as they should 
#pragma omp single 
{ 
    //everything in here is executed by one thread as it should be 
} 
    #pragma omp barrier //this is the barrier in which threads run ahead 
    par_time(cc_time_tot, phi_time_tot, psi_time_tot); 
    #pragma omp barrier 
} 
//do more stuff 

지금 설명하기는. 내 병렬 영역의 시작 부분에서 myId는 private로 설정되어 모든 스레드가 올바른 스레드 ID를 갖습니다. set_affinity()는 어떤 스레드가 어떤 코어에서 실행되는지를 제어합니다. 내가 가지고있는 문제는 #pragma omp for schedule (static, 1)이다.

블록은 :

if (myId<myConstant) 
    { 
    #pragma omp for schedule(static,1) 
    for(count = 0; count < AnotherConstant; count++) 
     { 
     //Do stuff, everything runs as it should 
     } 
    } 

내가 myConstant-1을 통해 스레드의 특정 숫자 0을 통해 배포 할 몇 가지 작업을 나타냅니다. 이 스레드에서 (schedule (static, 1)이하는 방식으로) 루프의 반복을 분산 시키려 고합니다. 이것은 모두 올바르게 수행됩니다.

그런 다음 코드가 단일 영역에 들어가면 거기에있는 모든 명령이 그대로 수행됩니다. 하지만 myConstant를 2로 지정한다고 가정 해 봅시다. 그런 다음 3 개의 스레드 이상으로 실행하면 단일 재질의 모든 항목이 올바르게 실행되지만 ID가 3 이상인 스레드는 단일 명령의 모든 명령이 완료 될 때까지 기다리지 않습니다.

단일 스레드 내에서 모든 스레드가 수행하는 작업을 만드는 함수가 호출됩니다. id가 3 이상인 스레드 (일반적으로 myConstant 이상)는 계속 진행되어 par_time()을 실행하고 다른 스레드는 여전히 단일 스레드에서 실행되는 함수에 의해 생성 된 작업을 수행합니다. par_time()은 각 쓰레드에 대한 데이터를 출력한다.

schedule (static, 1)에 대한 pragma omp를 주석 처리하고 단일 스레드에서 for 루프를 실행하면 (예 : if (myId == 0) if 문을 변경) 모든 것이 작동합니다. 그래서 나는 왜 앞에서 언급 한 스레드가 계속 앞으로 나아가고 있는지 확신 할 수 없다.

혼란스러운 점이 있으면 알려주세요. 특정 문제입니다. OMP를 사용하여 내 흐름 제어의 결함을 본 사람을 찾고있었습니다. 당신의 OpenMP V3.0 스펙을 보면

+0

음, 수정 사항을 발견 한 것으로 보이지만 그 이유는 확실하지 않습니다. if 문을 주석 처리하면 문제가 해결되고 AnotherConstant를 통해 스레드 0 만 for 루프 내에서 사용되는 것 같습니다. 그래도 보장이 있니? 에서처럼 어떤 ID를 가진 스레드가 for 루프 내에서 사용될 수 있거나 항상 AnotherConstant를 통해 0이 될 수 있습니다. – WtLgi

답변

6

, 섹션 2.5은 작업 공유를 구축, 상태 :

  • 각 작업 공유 영역에 의해 발생해야합니다

    다음과 같은 제한이 작업 공유 구조에 적용 팀 내의 모든 스레드 또는 전혀 없음

  • 발생하는 작업 공유 영역 및 배리어 영역의 시퀀스 팀의 모든 스레드에 대해 이 동일해야합니다. 내을위한하여 작업 공유를 가짐으로써

당신은 당신의 프로그램이 부적합하고 이러한 제한을 모두 위반 한 경우. 규격을 따르지 않는 OpenMP 프로그램은 사양에 따라 "지정되지 않은"동작을합니다.

일정 유형이 "정적 1"인 for 루프를 실행하는 데 사용되는 스레드에 대해 작업의 첫 번째 청크 (이 경우 count = 0)가 스레드 0에 할당됩니다. 다음 청크 (count = 1)는 모든 청크가 할당 될 때까지 스레드 1 등에 할당됩니다. 스레드보다 많은 청크가 있으면 라운드 로빈 방식으로 스레드 0에서 할당이 다시 시작됩니다. OpenMP 스펙 2.5.1 섹션에서 정확한 구문을 읽을 수 있습니다. 여기서는 스케줄 절에 대해 설명합니다.