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