2014-07-11 8 views
2

몇 가지 기본 구성 (컨텍스트, 명령 대기열 등)을 제공하는 라이브러리 (Windows 시스템의 공유 라이브러리)를 만들고 싶습니다. 문제는 응용 프로그램이 종료하려고 할 때 액세스 위반이 발생한다는 것입니다. 내 첫 번째 추측은 내 래퍼 구현에 문제가 될 수 있지만 공식 C++ 래퍼 (cl.hpp)를 사용하는 테스트 사례를 작성한 것입니다. 공유 라이브러리 applcation 측OpenCL - C++ 래퍼 - 동적 라이브러리의 컨텍스트 초기화가 액세스 위반으로 연결됩니다.

int main(int argc, char** argv) { 
    cpu(); 
} 

그래서 아주 간단 물건에

boost::optional<cl::Context> cpuContext; 
void cpu() { 
    cpuContext = cl::Context(CL_DEVICE_TYPE_CPU); 
} 

에서

...

흥미로운 것은이 만에 발생되는 인텔 런타임 (인텔 GPU는 테스트 할 수 없음)이 제공하는 런타임은 지원되지 않습니다. 엔비디아. 또한 응용 프로그램에서 cpuContext 변수가 선언 된 경우에도 발생하지 않습니다.

내 질문은 :
이것은 인텔 런타임의 버그입니까, 아니면 뭔가를 놓치고 정의되지 않은 동작이 발생 했습니까?

+0

cl.hpp 내에서 실제 OpenCL API 호출을 중단하고 이들이 합법적인지 (생성 또는 보관할 때마다 릴리스 됨) 볼 수 있습니다. – Dithermaster

답변

3

DllMain에서 OpenCL 개체를 릴리스하려고하면 매우 미묘한 문제가 발생할 수 있습니다. 보고있는 동작을 표시 할 수는 있지만 예측할 수 없거나 간헐적 일 수 있습니다. 먼저 작은 배경 :

대부분의 플랫폼에서 시스템에 존재할 수있는 다양한 구현과 코드 사이의 심플한 표준 설치 가능 클라이언트 드라이버 (ICD)를로드하고 있습니다. 자세한 내용은 here을 참조하십시오. ICD는 Windows LoadLibrary 호출을 사용하여 OpenCL 공급 업체 (Intel, AMD 등)가 제공 한 DLL을로드하는 DLL입니다.

LoadLibrary를 사용하면 Windows DLL 종속성 추적 구조가 업데이트되지 않습니다. 따라서 프로세스가 종료되면 해당 DLL이 언로드되는 순서를 알 수있는 방법이 없습니다. 이 경우 공급 업체가 제공 한 OpenCL DLL은 글로벌 OpenCL 컨텍스트 개체의 소멸자가 호출 될 때까지 이미 언로드되었을 수 있습니다. 이 액세스 위반이 발생할 수 있습니다. here에 대해 자세히 알아볼 수 있습니다.

이 모든 것을 감안할 때 OpenCL 함수가 전역 개체 소멸자 또는 DllMain에서 호출되어야하는 DLL을 디자인하지 않아야합니다.