2011-11-02 5 views
4

프로젝트의 경우 OpenCL로 들어가야했습니다. 이제는 원자 연산이 필요하다는 것을 제외하고는 상당히 잘 진행되고 있습니다. 마지막 드라이버가있는 Nvidia GPU에서 OpenCL 코드를 실행하고 있습니다. clGetDeviceInfo()CL_DEVICE_VERSION을 쿼리하면 OpenCL 1.0 CUDA이 반환되므로 OpenCL 1.0 사양을 참조해야합니다. atom_add(&vnumber[0], 1); : OpenCL 원자 추가 연산의 이상한 동작

은 내가 __global int* vnumber 버퍼 내 커널에 atom_add 작업을 사용하기 시작했다. 이것은 분명히 잘못된 결과를 낳았습니다. 따라서 추가 검사로서 add 명령을 커널 시작 부분으로 이동하여 각 스레드에 대해 실행되도록했습니다. 커널이 512 x 512 스레드로 시작될 때, vnumber[0]의 내용은 정확히 2 x 512 x 512 인 524288입니다. 재미있는 점은 추가 작업을 atom_add(&vnumber[0], 2);으로 변경하면 반환 값은 65536으로 다시 2 배가됩니다.

누군가 이미 비슷한 것을 경험 했습니까? 나는 아주 기본적인 것을 놓치고 있습니까? 데이터 유형의 정확성을 확인했지만 확인 (나는 *int 버퍼를 사용하고 sizeof(cl_int)과 함께 할당 함).

답변

3

로컬 메모리 용 OpenCL 1.0 확장 인 atom_add를 사용하고 있습니다. 그러나 당신은 글로벌 메모리를 전달하고 있습니다. 대신 전역 메모리와 함께 작동하는 OpenCL 1.1의 atomic_add를 사용해보십시오.

+0

내 CL_DEVICE_VERSION을 쿼리하면 OpenCL 1.0이 반환되므로 다음 사양을 참조하십시오. [link] (http://r00tsecurity.org/db/cheat-sheets/Programming/OpenCL/opencl-quick-reference-card.pdf) . 원자는 확장 기능으로 구현되었으므로 GPU는 "cl_khr_global_int32_base_atomics"확장자를 지원하므로 전역 메모리 버퍼에서만 아토믹을 사용할 수 있습니다. 또는 최소한 글로벌 메모리. 또한 버전 1.0 만 지원되는 것으로 보이는 경우 atomic_add 명령어를 사용할 수 있습니까? – Neenster

+4

atom_add와 atomic_add의 차이점은 전역 메모리에서 작동하지 않는다는 것입니다. cl_khr_ (전역 또는 로컬) _int (크기) _ (기본 또는 확장) _atomics가 있으며 그 중 하나가 내장되어 있습니다. 필요한 것을 글로벌 및/또는 로컬 버전에서 활성화해야합니다. atom_ *은 확장이고 atomic_는 내장 된 것입니다. 또한 포인터는 휘발성이 필요합니다. – arsenm