수색…


소개

이 항목에서는 장치에서 데이터를 액세스 할 수있는 다른 위치에 데이터를 배치하는 여러 가지 방법에 대해 중점적으로 설명합니다.

배열 읽기

장치에서 호스트로 배열을 다시 읽으려면,

clEnqueueReadBuffer($queue, $memobj, $blocking, $offset, $size, $target, 0, null, null);

$ 큐는 장치의 메모리를 할당하는 데 사용 된 CommandQueue입니다. $ memobj는 장치 메모리에 대한 주소를 포함하고 $ offset과 $ size는 복사되는 데이터의 양과 양을 정의합니다. $ target은 데이터가 저장 될 호스트 메모리에 대한 포인터입니다. $ target은 할당되고 적절한 크기를 가져야합니다.

질감 읽기

이미지를 읽는 것은 배열을 읽는 것과 거의 같습니다. 유일한 차이점은 크기와 오프셋이 3 차원이어야한다는 것입니다.

clEnqueueReadImage($queue, $memobj, $blocking, $offset, $size, $stride, $slice_pitch, $target, 0, null, null);

$ stride는 행에 몇 바이트가 있는지 정의합니다. 일반적으로 이것은 너비 * (픽셀 당 바이트)이지만 누군가가 메모리 뱅크와 데이터를 정렬하기 위해이를 변경하려고 할 수 있습니다. $ slice_pitch에 대해서도 마찬가지이며이 값은 세 번째 차원에 대한 것입니다.

2D 텍스처 쓰기

장치에 텍스처를 복사하려면 두 단계가 필요합니다.

  1. 장치에 메모리 할당
  2. 이미지를 장치로 복사
  _mem = clCreateImage2D($context, $mem_flags, $image_format, $width, $height, $stride, $source, &err);

$ mem_flags는 메모리 할당 방법을 정의합니다. 읽기 전용, 쓰기 전용 또는 둘 다일 수 있습니다. 또한 메모리가 할당 된 위치와 방법을 정의 할 수 있습니다. $ width, $ height 및 $ stride는 매우 자명합니다.

mem_flags가 데이터를 복사하면 완료됩니다. 나중에 수동으로 처리하려면 준비가되었을 때 다른 기능을 호출해야합니다.

err = clEnqueueWriteImage($queue, _mem, $blocking, $offset, $size, $stride, $slice_pitch, $source, 0, null, null);

$ offset과 $ size는 대상 메모리에 복사 할 이미지 영역을 정의합니다. $ stride는 행에 몇 바이트가 있는지 정의합니다. 일반적으로 이것은 너비 * (픽셀 당 바이트)이지만 누군가가 메모리 뱅크와 데이터를 정렬하기 위해이를 변경하려고 할 수 있습니다. $ slice_pitch에 대해서도 마찬가지이며이 값은 세 번째 차원에 대한 것입니다. $ stride와 $ slice_pitch 모두 입력 데이터와 일치해야합니다.

메모리 플래그

메모리를 할당 할 때 다른 모드 중에서 선택할 수 있습니다 :

  • 읽기 전용 메모리
  • 메모리 만 쓰기
  • 메모리 읽기 / 쓰기

읽기 전용 메모리는 __constant 메모리 영역에 할당되고 나머지 두 개는 정상 __global 영역에 할당됩니다.

액세스 가능성 외에도 메모리가 할당되는 위치를 정의 할 수 있습니다.

  • 지정되지 않음 : 메모리는 예상 한대로 장치 메모리에 할당됩니다. $ 소스 포인터는 null로 설정할 수 있습니다.
  • CL_MEM_USE_HOST_PTR : 이것은 데이터가 시스템 RAM에 있고 이동하지 않아야 함을 장치에 알려줍니다. 대신 데이터는 램에서 직접 조작됩니다.
  • CL_MEM_COPY_HOST_PTR : 지정된 주소의 모든 값을 장치 메모리에 복사하거나 CL_MEM_ALLOC_HOST_PTR을 사용하여 시스템 램의 별도 메모리 영역에 복사하도록 장치에 지시합니다.
  • CL_MEM_ALLOC_HOST_PTR : 시스템 RAM에 공간을 할당하도록 장치에 지시합니다. 유일한 매개 변수로 사용되면 $ 소스 포인터를 null로 설정할 수 있습니다.

속도면에서는 장치 전역 메모리에 대한 액세스가 가장 빠릅니다. 그러나 데이터를 복사하려면 두 번 호출해야합니다. Alloc_host_ptr은 더 빠른 속도를 제공하는 반면, 호스트 포인터를 사용하는 것이 가장 느립니다.

use_host_ptr을 사용할 때 장치는 정확히 다음을 수행합니다. 시스템 램에서 데이터를 사용합니다. 물론 os에 의해 호출됩니다. 따라서 모든 메모리 호출은 잠재적 인 페이지 오류를 처리하기 위해 CPU를 거쳐야합니다. 데이터가 사용 가능할 때, CPU는 그것을 고정 메모리에 복사하고이를 귀중한 CPU 클럭 사이클을 사용하여 DMA 컨트롤러로 전달합니다. 반대로 alloc_host_ptr은 시스템 램에 고정 된 메모리를 할당합니다. 이 메모리는 pageswap 메커니즘 외부에 배치되므로 가용성이 보장됩니다. 따라서 시스템 램에 액세스 할 때 장치가 CPU를 완전히 건너 뛸 수 있고 DMA를 사용하여 데이터를 장치에 빠르게 복사 할 수 있습니다.

배열 쓰기

배열 쓰기는 두 단계로 구성됩니다.

  1. 메모리 할당
  2. 데이터 복사

메모리를 할당하기위한 간단한 호출

_mem = clCreateBuffer($queue, $mem_flags, $size, $host_ptr, &err);

충분하다. mem_flags를 통해 호스트 포인터를 복사하기로 결정했다면 완료됩니다. 그렇지 않으면 언제든지 데이터를 복사 할 수 있습니다.

err = clEnqueueWriteBuffer($queue, _mem, $blocking, $offset, $size, $source, 0, null, null);


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow