2016-11-18 2 views
2

같은 문제를 다루는 스택 오버플로에 대해 몇 가지 질문을 보았지만 확실한 답변은 없습니다. 나는 내 자신의 질문들로 다시 물을 것이라고 생각했다. 모두는 당면한 주제와 관련이 있습니다.언제 OpenCL 데이터 전송이 발생합니까?

따라서 호스트에서 openCL 장치로의 데이터 전송이 언제 발생하는지 알고 있습니까?

clCreateBuffer()

clSetKernelArg()

clEnqueueNDRangeKernel() : 당신은 나에게 아래의 기능 (?이 함수가 호출 될 때 즉, 어떤 데이터가있는 경우, 전송 또는 생성한다)의 정확한 메모리 전송 작업을 말할 수

첫 번째 두 개는 이벤트를 생성하지 않으므로 시간을 측정 할 수 없지만 일부 데이터는 여기에서 발생합니다.

먼저 커널 arg로 설정하지 않고 데이터를 장치로 전송할 수 있습니까?

CL_MEM_USE_HOST_PTR으로 생성 된 mem 개체가 장치에 의해 직접 조작되는 것으로 나타납니다 (자체 테스트 결과). 왜 그렇게 바람직하지 않을까요? 그런 식으로, 우리는 더 많은 데이터 전송 명령을 피할 수 있습니다. (그리고 확실히 드라이버가 이것을 가장 효율적으로 구현합니다.)

커널이 반환 한 후에 전송 된 데이터 (예 : 커널 arg의 파)가 장치에 머물러 추가 조작이 가능합니까? 없다면 그냥 할 수있는 방법이 있습니까?

답변

2

버퍼 복사본은 명령 대기열과 관련이 있습니다. 명령 대기열은 가장 쉬운 방법으로 finish()을 사용하여 호스트와 동기화됩니다.

clCreateBuffer() 

    clEnqueueWriteBuffer() <-------- you can get event data from this 
     (set blocking parameter to false to queue everything quickly) 
     (set blockinig to true if you sync write here) 

clSetKernelArg() 

    clEnqueueWriteBuffer() <----- it could be here too 

clEnqueueNDRangeKernel() 

    clEnqueueWriteBuffer() <----- or here (too quickly re-set an array?) 

clFinish() <--------- this ensures all queued commands are executed before this 

now you can query data of that event to check when it started and when ended 

버퍼를 장치에 유지하려면 장치에 먼저 버퍼를 만들고 다른 장치로 마이그레이션하지 않아야합니다. createBuffer()CL_MEM_READ_WRITE 플래그 만 사용하면 버퍼를 해제 할 때까지 장치 측에서 실제 버퍼가됩니다.

장치가 코어에 매핑 할 때 CL_MEM_USE_HOST_PTR 또는 CL_MEM_ALLOC_HOST_PTR은 호스트 메모리를 사용합니다. 이것은 호스트 측에서 여분의 데이터 이동이 필요 없기 때문에 데이터 스트리밍 인 및 아웃을 위해 더 빠릅니다. 고속 gddr5 또는 hbm과 같은 장치 메모리를 항상 사용해야하는 경우이 플래그를 사용하면 안됩니다.

한 번 장치에 복사하고 원하는만큼 사용하십시오. 기기에 자체 메모리가있는 경우 예를 들어, Intel HD Graphics 400에는 자체 메모리가 없으므로 RAM을 공유하므로 CL_MEM _..._ HOST_PTR 플래그 및 특히 USE_HOST_PTR 플래그를 사용하는 것이 훨씬 빠릅니다.

장치가 RAM을 CPU와 공유하는지 확인하려면 장치의 CL_DEVICE_HOST_UNIFIED_MEMORY 속성을 쿼리하십시오.

는이 CL_MEM_USE_HOST_PTR로 만든 MEM 객체 직접 심지어지도없이 장치

에 의해 조작 가져옵니다 (내 자신의 예비 시험에서) 표시/매핑 해제 명령이 실행 커널 pror, 내 컴퓨터 동일하게 행동하지만 맵/맵핑을 사용하여 안전하고 너무 많은 사이클에 세금을 부과하지 않습니다.

편집 : 사용자가 원하는 전에 명령이 시작되지 않도록하려면, bufferwrite 명령의 이벤트 목록 입력 매개 변수에 사용자 이벤트를 추가 할 수 있습니다. 그런 다음 명령이 목록의 모든 이벤트가 시작되기를 기다리거나 계속하기 전에 완료 될 때까지 기다리는 사용자 이벤트를 트리거 할 수 있습니다 (이벤트 목록 입력 매개 변수에 지정된 것이 있으면)

관련 문제