2011-01-27 4 views
3

난 그냥 다음 코드 (GCC 4.5.1에서) OpenMP를 컴파일하지 않는 것으로 나타났습니다 :OpenMP : 포인터 대상 플러시 방법?

struct job { 
    unsigned busy_children; 
}; 

job* j = allocateJob(…); 
// … 

#pragma omp flush(j->busy_children) 

컴파일러는 플러시 인수 목록에서 ->에 대해 불평하고, OpenMP를 따라 사양이 맞다 : flush은 기본적으로 (한정된) ID 만 허용된다는 식의 "id-expression"목록을 인수로 사용합니다.

포인터가 목록에 있으면

포인터 자체 플러싱 아닌 메모리 블록 포인터가 참조하는 :

또한, 규격이 약 flush 놓았 말한다.

물론. 그러나, OpenMP 또한 나를 역 참조 포인터를 허용하지 않기 때문에 나는 기본적으로 pointee (포인터 대상)을 플러시 수 없습니다.

- 그러면 참조는 어떻게됩니까? 사양은 그들에 대해 언급하지는 않지만 다음 사항들이 적합하다는 것을 확신하지 못하고 실제로 pointee를 플러시 할 것입니다.

unsigned& busy_children = j->busy_children; 
#pragma omp flush(busy_children) 

작동 여부가 보장됩니까?

그렇지 않은 경우, 어떻게 뾰족점을 없앨 수 있습니까?

+0

MSDN에 따르면 "플러시 지시어에 지정된 변수에는 참조 유형이 없어야합니다." 따라서 모든 ** 플랫폼에서 작동하는 것은 보장되지 않습니다. GCC에 대해 알지 못합니다. –

+0

@Kyrill : Ah, f * ck. 그건 그렇고, OpenMP 스펙은 분명히 ** 3.0 ** 2.5도 언급하지 않습니다. 그리고 섹션 번호 매기기는 MSDN에서 다릅니다. –

답변

2

flush 지시문은 OpenMP ARB에 오랜 시간 동안 두통을주었습니다. 너무나 많은데, 그것을 완전히 제거하는 것에 대한 이야기가있었습니다 -하지만 그것은 다른 문제를 만듭니다. flush (list)를 사용하면 문제를 해결하기가 극도로 어렵고 OpenMP 전문가도 문제를 해결하는 데 많은 어려움을 겪습니다. 문제는 정의 된 방식으로 컴파일러에서 코드 내에서 이동할 수 있다는 것입니다. 즉, flush (list)를 사용하지 말아야합니다.

pointee를 플러시 할 수 있다는 것에 대한 질문은 플러시 (목록 없음)를 사용하는 것뿐입니다. 이렇게하면 전체 스레드 환경이 플러시되고 컴파일러에서 이동할 수 없습니다. "무거워"보이지만 컴파일러는 목록없이 flush를 사용할 때 필요한 것을 플러시하는 데 실제로 꽤 좋습니다.

+0

글쎄, 그건 좀 짜증나. 이 통찰력을 공유해 주셔서 감사합니다. 나는 그때 쓰라린 환약을 삼키고, 전체 환경을 내뿜을 것이다. 나는 그 참조를 플러시 할 필요가있다. –

1

OpenMP 사양은 변수 유형에 대해 직접적으로 말하지 않지만 MSDN은 "플러시 지시문에 지정된 변수에 참조 형식이 없어야합니다"라고 말합니다. 이것은 내가 이것이 작동하도록 보장되지 않는다고 생각하게 만듭니다. 빈 변수 목록이있는 flush 지시문은 모든 메모리를 플러시해야 안전하게 사용할 수 있습니다.