2014-04-24 10 views
0

호스트 OpenMP 코드에서 인텔의 오프로드 플러그 마스크를 사용하고 있습니다. 코드는 다음과 같습니다.호스트 openMP 병렬 영역의 Xeon-Phi 비동기 오프로드

int s1 = f(a,b,c); 

#prama offload singnal(s1) in (...) out(x:len) 
{ 
    for (int i = 0; i < len; ++i) 
    { 
     x[i] = ... 
    } 
} 

#pragma omp parallel default(shared) 
{ 
    #pragma omp for schedule(dynamic) nowait 
    for (int i = 0; i < count; ++i) 
    { 
     /* code */ 
    } 

    #pragma omp for schedule(dynamic) 
    for (int j = 0; j < count2; ++j) 
    { 
     /* code */ 
    } 
} 

#pragma offload wait(s1) 
{ 
    /* code */ 
} 

MIC에 대한 코드 오프로드 계산은 $ x $입니다. 이 코드는 CPU 코어에 대한 일부 openMP를 설정하여 스스로를 바쁘게 유지합니다. 위의 코드는 예상대로 작동합니다. 그러나 첫 번째 오프로드 pragma는 많은 시간이 걸리고 병목 현상이되었습니다. 그럼에도 불구하고 전반적으로 MIC에 $ x $의 계산 부담을 덜어줍니다. , SO이 새로운 코드

int s1 = f(a,b,c); 

#pragma omp parallel default(shared) 
{ 
    #pragma omp single nowait 
    { 
     #prama offload singnal(s1) in (...) out(x:len) 
     { 
      for (int i = 0; i < len; ++i) 
      { 
       x[i] = ... 
      } 
     } 

    } 

    #pragma omp for schedule(dynamic) nowait 
    for (int i = 0; i < count; ++i) 
    { 
     /* code */ 
    } 

    #pragma omp for schedule(dynamic) 
    for (int j = 0; j < count2; ++j) 
    { 
     /* code */ 
    } 
} 

#pragma offload wait(s1) 
{ 
    /* code */ 
} 

를 다음과 기타의 OpenMP 스레드가 다른 작업 공유 구조에 사용할 수있는 상태에서 오프로드를 수행 할 스레드를 할당 잠재적으로 내가 노력하고있어이 대기 시간 문제를 극복하는 한 가지 방법이다. 그러나이 코드는 작동하지 않습니다. 다음과 같은 오류 메시지가 표시됩니다.

device 1 does not have a pending signal for wait(0x1) 

위의 코드 부분이 오프로드되는 주요 원인입니다. 한 가지 임시 해결 방법은 상수를 신호, 즉 작동하는 신호 (0)로 사용하는 것입니다. 그러나 더 영구적 인 솔루션이 필요합니다. 아무도 내 코드에서 무슨 일이 일어나고 있는지 불빛을 그늘지게 할 수 있습니까?

감사합니다.

+0

이것은 https://software.intel.com/en-us/forums/topic/509845 당신의 응답을 – Jeff

답변

0

제 2 코드 블록에 주석을 달 수 없습니다. 나는 처음에 대해 몇 가지 관찰을했다.

첫 번째 오프로드는 오프로드 인프라를 설정하기 때문에 항상 더 오랜 시간이 걸립니다. 이 구조체에는 환경 변수 전달, libomp5의 마이크 구현을 통한 복사, 스레드 풀 설정 등이 포함됩니다.

이 문제를 피하는 방법은 먼저 더미 오프로드를 설정하는 것입니다. 아무것도 아니며 계산 블록의 일부가 아닙니다.

xeon Φ 보조 프로세서 최적화에 대한 유용한 참조 정보는 software.intel.com/mic-developer의 교육 탭에 있습니다.

또한보십시오 software.intel.com/en-us/articles/programming-and-compiling-for-intel-many-integrated-core-architecture, software.intel.com/en-us/articles/intel-xeon-phi-coprocessors-part-1 최적화를위한 최적화 및 성능 조정 및 software.intel.com/en-us/articles/optimization-and-performance-tuning-for-intel- 제온 - 코 - 코 프로세서 - 파트 -1 최적화.

죄송합니다. 긴 URL은 죄송하지만 stackoverflow는 내가 새로운 링크 인만큼 링크를 3 개 이상 포함 할 수 없습니다.

+0

감사의 중복입니다. 이 전체 코드 블록은 순차 for 루프 안에 있습니다. 따라서 함수는 for-loop의 모든 반복에서 호출됩니다. 초기화는 바깥 for 루프 전에 수행됩니다. 이 초기화는 나의 경우에 7 초가 걸린다 (malloc의 엄청난 수 때문에). malloc 라운드가 끝나면 할당 된 모든 영역을 "재사용"합니다. 나는이 7 초를 모두 무시하고있다. 그것은 내부 outer-for-loop이고, 4 밀리 초가 걸리는 각각의 MIC 오프로드는 내가 숨기려고하는 것입니다. – zimbra314

1

테일러의 답변을 조금 보완 해 드리겠습니다.

초기화 작업이 계속 진행되기 때문에 실제로 첫 번째 오프로드가 후속 오프로드보다 더 많은 시간이 걸립니다. 테일러는 거기에서 진행되는 일들을 스케치했습니다. OFFLOAD_INIT = on_start 환경 변수를 사용하여 더미 오프로드를 피할 수 있습니다. 그것은 런타임 시스템이 모든 초기화를 미리 수행하도록해야합니다. 이 오버 헤드는 사라지지 않지만 첫 번째 오프로드에서 응용 프로그램 초기화로 이동합니다.

두 번째 코드 스 니펫의 문제는 오프로드가 다른 장치를 대상으로하는 것 같습니다. 신호 및 대기는 동일한 대상 장치에 대해 발생하는 경우에만 작동합니다. 오프로드와 함께 target(mic:0) 절을 명시 적으로 사용하지 않으므로 런타임 시스템이 다른 대상 장치를 선택할 확률이 높습니다.

하나의 권장 사항은 신호에 일반 정수를 사용하지 않는 것입니다. 일반적으로 신호는 특정 버퍼가 준비되었음을 나타냅니다. 이러한 경우 버퍼 포인터를 신호 핸들로 사용하는 것이 좋습니다. 다른 버퍼로 작업하는 동시 오프로드에 대해 고유하기 때문입니다.

건배, -Michael

+0

그들은 같은 장치를 목표로 삼고 있습니다. 즉 mic : 1입니다. 그리고 이것은 명시 적으로 행해진 다. – zimbra314