내 GPU는 무엇을 기다리고 있습니까?


11

AMD Radeon HD 7800 시리즈 GPU와 함께 사용할 OpenCL 프로그램을 작성 중입니다. AMD의 OpenCL 프로그래밍 가이드 에 따르면 ,이 세대의 GPU에는 비동기 적으로 작동 할 수있는 두 개의 하드웨어 대기열이 있습니다.

5.5.6 명령 대기열

남섬 및 그 이후의 장치는 최소한 두 개의 하드웨어 계산 대기열을 지원합니다. 이를 통해 응용 프로그램은 비동기 제출 및 실행을 위해 두 개의 명령 대기열로 소규모 디스패치의 처리량을 증가시킬 수 있습니다. 하드웨어 계산 대기열은 다음 순서로 선택됩니다. 첫 번째 대기열 = 짝수 OCL 명령 대기열, 두 번째 대기열 = 홀수 OCL 대기열.

이를 위해 GPU에 데이터를 공급하기 위해 두 개의 별도 OpenCL 명령 대기열을 만들었습니다. 대략 호스트 스레드에서 실행되는 프로그램 은 다음과 같습니다.

static const int kNumQueues = 2;
cl_command_queue default_queue;
cl_command_queue work_queue[kNumQueues];

static const int N = 256;
cl_mem gl_buffers[N];
cl_event finish_events[N];

clEnqueueAcquireGLObjects(default_queue, gl_buffers, N);

int queue_idx = 0;
for (int i = 0; i < N; ++i) {
  cl_command_queue queue = work_queue[queue_idx];

  cl_mem src = clCreateBuffer(CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, ...);

  // Enqueue a few kernels
  cl_mem tmp1 = clCreateBuffer(CL_READ_WRITE);
  clEnqueueNDRangeKernel(kernel1, queue, src, tmp1);

  clEnqueueNDRangeKernel(kernel2, queue, tmp1, tmp1);

  cl_mem tmp2 = clCreateBuffer(CL_READ_WRITE);
  clEnqueueNDRangeKernel(kernel2, queue, tmp1, tmp2);

  clEnqueueNDRangeKernel(kernel3, queue, tmp2, gl_buffer[i], finish_events + i);

  queue_idx = (queue_idx + 1) % kNumQueues;
}

clEnqueueReleaseGLObjects(default_queue, gl_buffers, N);
clWaitForEvents(N, finish_events);

을 사용 kNumQueues = 1하면이 응용 프로그램은 의도 한대로 작동합니다. 모든 작업을 단일 명령 대기열로 수집 한 다음 GPU가 전체 시간 동안 상당히 바쁠 때까지 완료됩니다. CodeXL 프로파일 러의 출력을 보면 이것을 볼 수 있습니다.

여기에 이미지 설명을 입력하십시오

그러나을 설정 kNumQueues = 2하면 동일한 일이 발생할 것으로 예상되지만 작업이 두 대기열에 균등하게 분할됩니다. 어쨌든 각 큐는 하나의 큐와 개별적으로 동일한 특성을 갖기를 기대합니다. 모든 것이 완료 될 때까지 순차적으로 작동하기 시작합니다. 그러나 두 개의 대기열을 사용할 때 모든 작업이 두 개의 하드웨어 대기열에 분할되는 것은 아닙니다.

여기에 이미지 설명을 입력하십시오

GPU 작업이 시작될 때 대기열은 일부 커널을 비동기식으로 실행하도록 관리하지만 하드웨어 대기열을 완전히 차지하지는 않습니다 (내 이해가 잘못되지 않는 한). GPU 작업이 끝날 무렵 대기열이 하드웨어 대기열 중 하나에 만 순차적으로 작업을 추가하는 것처럼 보이지만 커널이 실행되지 않는 경우가 있습니다. 무엇을 제공합니까? 런타임 작동 방식에 대한 근본적인 오해가 있습니까?

왜 이런 일이 일어나고 있는지에 대한 몇 가지 이론이 있습니다.

  1. 산재 된 clCreateBuffer호출로 인해 GPU가 공유 메모리 풀에서 장치 리소스를 동 기적으로 할당하여 개별 커널 실행을 중단시킵니다.

  2. 기본 OpenCL 구현은 논리적 대기열을 물리적 대기열에 매핑하지 않으며 런타임에 객체를 배치 할 위치 만 결정합니다.

  3. GL 객체를 사용하고 있기 때문에 GPU는 쓰기 중에 특별히 할당 된 메모리에 대한 액세스를 동기화해야합니다.

이러한 가정 중 하나라도 사실입니까? 누구나 2 큐 시나리오에서 GPU가 대기하는 원인을 알고 있습니까? 모든 통찰력에 감사드립니다!


프로그래밍 가이드에 두 개의 하드웨어 큐가 있다고 말하는 곳을 찾을 수 없습니다. 문서에서 견적을 게시 할 수 있습니까? 두 개의 대기열이 있다고 말하는 장을 언급하십시오. OpenCL을 사용하여 런타임에 여러 개의 하드웨어 큐를 쿼리 할 수 ​​있습니까?
Andreas

내 게시물을 업데이트했습니다. 가능한 실행 이라고 말하지만 몇 가지를 할 수 있다면 왜 모두 할 수 없습니까? 또한 OpenCL 런타임에는 하드웨어 큐 개념이 없으므로 쿼리 할 수있는 것이 아닙니다.
Mokosha

답변:


2

일반적으로 컴퓨팅 큐가 반드시 2 배 디스패치를 ​​동시에 수행 할 수있는 것은 아닙니다. 계산 단위를 완전히 포화시키는 단일 대기열은 처리량이 더 좋습니다. 하나의 큐가 적은 리소스 (공유 메모리 또는 레지스터)를 소비하면 보조 큐가 동일한 계산 단위에서 겹칠 수있는 경우 여러 큐가 유용합니다.

실시간 렌더링의 경우 컴퓨팅 / 쉐이더에서는 매우 가볍지 만 고정 기능 하드웨어에서는 무거운 섀도 렌더링과 같은 경우가 특히 그러하므로 GPU 스케줄러가 보조 큐 비동기를 실행할 수 있습니다.

또한 릴리스 노트에서이를 발견했습니다. 그것이 같은 문제인지 알지 못하지만 CodeXL이 좋지 않을 수도 있습니다. 나는 파견이 진행되는 최고의 계측기를 가지고 있지 않을 것으로 기대합니다.

https://developer.amd.com/wordpress/media/2013/02/AMD_CodeXL_Release_Notes.pdf

동시 비동기 데이터 전송 및 커널 실행을 수행하는 응용 프로그램의 경우 응용 프로그램 추적 세션보기에 표시된 타임 라인에 이러한 작업이 겹치는 것으로 표시되지 않습니다. 프로파일 링하는 동안 드라이버와 하드웨어가 이러한 작업을 동 기적으로 수행하기 때문입니다. (333981)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.