2016-11-10 2 views
1

Opencl에서 버퍼는 호스트 응용 프로그램에서 데이터가 전달되는 도관입니다. 내가 a_bufferREAD_ONLY로 즐겨 찾기에 추가되었습니다 버퍼를 가지고 있고, 커널 인 경우OpenCL - 버퍼와 전역 메모리의 차이

cl_mem clCreateBuffer (cl_context context, cl_mem_flags flags, size_t size, 
         void *host_ptr, cl_int *errcode_ret); 

지금 : a_buffer는 글로벌 메모리 또는 상수 메모리입니다 :

__kernel void two_buffer_double(__global float* a) 
{ 
    int i = get_global_id(0); 
    float b = a[i] * 2; 
} 

내 질문이다? a__constant 한정자를 사용해야합니까? cl_mem_flags (READ_ONLYREAD_WRITE)와 메모리 한정자 (globalconstant) 사이의 연결은 무엇입니까?

+0

"호스트 측"부분에 대한 정보가 더 추가되었습니다. –

답변

2
__constant 

한정자는 일정한 메모리에 사용되며 일부 카드는 텍스쳐 캐시를 얻을 __global에서 독립적으로 대역폭을 얻을 수 있지만, 매우 크기가 제한됩니다.

__global __read_only * float 

수단 인 OpenCL 구현은 캐시에 넣어 (또는 다른 데이터 경로를 사용) 하드웨어는 적합한 경우 노력할 것입니다하지만 (예를 들어, 단지 64KB의 대신 전용 VRAM 크기 나 비율에 의해 제한되어 있으므로 __global입니다)에 대한 __constant.

이 한정자는 장치 쪽 최적화를위한 것입니다.

호스트 측의 최적화 시간에는 버퍼 생성을위한 플래그로서

CL_MEM_READ_ONLY 

로 공급한다. 이것은 디바이스가 단지 DMA/pcie 액세스/캐싱 최적화를 사용하여 읽기만한다는 것을 의미하지만 enqueuewrite 또는 맵 unmap 조작을 사용하여 호스트 측 (디바이스가 아닌 C# C++ 코드와 같은 호스트)에서 쓸 수 있습니다.

__constant 

은 처리 할 데이터가 아니라 매개 변수 상수 정의입니다.

필터 코드를 작성하는 경우 데이터는 __global 일 수 있으며 필터 마스크는 액세스 할 수있는 마스크 바이트가 줄어들지 않으므로 __private 메모리 (최대 대역폭) 또는 __ 로컬 메모리 (개인용보다 느림)에 적합하지 않으면 __constant가 될 수 있습니다 데이터 대역폭. 당신이 그것을 선언 때문에

"글로벌 메모리 또는 상수 메모리 a_buffer입니까?"

이 장치 측 (커널 측)에 대한 전역 :

지금 당신의 질문에 대답 __global이지만 호스트 측 (하드웨어)의 어느 곳에 나있을 수 있습니다.

편집 : 호스트 측위한 는 USE_HOST_PTR 시스템 RAM으로부터는 직접 액세스 할 수있게하고없이 단지 CL_MEM_READ_WRITE와, 장치 측에만 가상 버퍼가 다른 플래그는 예를 들어, 사용되는 의존 장치 메모리는 RAM에 실제 버퍼와 매핑 된 섀도우를 가지며 (clenqueueread 또는 clenqueewrite에 대한 하위 단계로) 복사는 처음에는이 섀도우를 방문하여 gpu에 업로드됩니다.

예 장치 : 인텔 (R) HD (TM) 4GB의 DDR3L 노트북에서 그래픽 400 :

Query           value 
CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE     65536 bytes 
CL_DEVICE_GLOBAL_MEM_CACHE_SIZE     262144 bytes 
CL_DEVICE_GLOBAL_MEM_SIZE      1636414260 bytes 

CL_DEVICE_GLOBAL_MEM_CACHE_TYPE    CL_READ_WRITE_CACHE 
CL_DEVICE_LOCAL_MEM_SIZE      65536(vs constant, benchmark it) 
CL_DEVICE_LOCAL_MEM_TYPE      CL_LOCAL(so is faster than global) 

는하지만 중간 세그먼트 게임 AMD의 카드 전용 메모리 크기를 쿼리 할 수 ​​없습니다, 그것은 256KB입니다 스레드 그룹당. 그룹당 64 개의 스레드를 설정하면 전역 메모리로 유출되어 느려지 기 전에 (컴파일러 최적화로 인해) 스레드 당 4KB 레지스터 공간을 사용할 수 있습니다.

관련 문제