OpenCL: 실제 문제 - 페이지 4

 
TheXpert :

가장 무거운 방법은 FeedPatterns입니다.

즉, 속도를 높이는 것은 불가능합니다. 데이터 양과 관련하여 커널 에 대한 작업이 거의 없으며(많은 데이터, 적은 작업) 모든 이득은 앞뒤로 복사하여 소모됩니다.

VS에서는 컴파일러에 병렬화를 명시적으로 요청하거나 프로세서에 대한 병렬 스레드를 직접 생성할 수 있습니다.

OpenCL: от наивного кодирования - к более осмысленному
OpenCL: от наивного кодирования - к более осмысленному
  • 2012.06.05
  • Sceptic Philozoff
  • www.mql5.com
В данной статье продемонстрированы некоторые возможности оптимизации, открывающиеся при хотя бы поверхностном учете особенностей "железа", на котором исполняется кернел. Полученные цифры весьма далеки от предельных, но даже они показывают, что при том наборе возможностей, который имеется здесь и сейчас (OpenCL API в реализации разработчиков терминала не позволяет контролировать некоторые важные для оптимизации параметры - - в частности, размер локальной группы), выигрыш в производительности в сравнении с исполнением хостовой программы очень существенен.
 
TheXpert :
결국 MQL로 이적하게 됩니다.
그리고 그것은 엄격히 필요합니까? AMP라는 주제로 화를 내기까지 했습니다. 예전부터 들어가보고 싶었는데 여기가 이유가 있는듯..
 
kazakov.v :

즉, 속도를 높이는 것은 불가능합니다. 데이터 양과 관련하여 커널 에 대한 작업이 거의 없으며(많은 데이터, 적은 작업) 모든 이득은 앞뒤로 복사하여 소모됩니다.

VS에서는 컴파일러에 병렬화를 명시적으로 요청하거나 프로세서에 대한 병렬 스레드를 직접 생성할 수 있습니다.

글쎄, 왜 이러한 작업은 OpenCL에 완벽하게 들어 맞습니다.

 void Solver::FeedPattern( const Pattern &pattern)
  {
   size_t size=pattern.Size();

   assert(size==m_PatternSize);
   if (size!=m_PatternSize)
     {
       return ;
     }

   const std::vector< double >&values=pattern.Values();
   double etalon=pattern.Etalon();

   size_t i;

   for (i= 0 ; i<size;++i)
     {
       for (size_t j= 0 ; j<size;++j)
        {
         m_Matrix[i][j]+=values[i]*values[j];
        }
       m_Matrix[i][size]+=values[i];
      m_Matrix[i][size+ 1 ]+=values[i]*etalon;
     }

   for (i= 0 ; i<size;++i)
     {
      m_Matrix[size][i]+=values[i];
     }
   m_Matrix[size][size]+= 1 ;
   m_Matrix[size][size+ 1 ]+=etalon;
  }

그리고 녹색도.

 
Urain :

글쎄, 왜 이러한 작업은 OpenCL에 완벽하게 들어 맞습니다.

그리고 녹색도.

OpenCL과 C ++에 대한 구현 및 비교 테스트가 필요하며 증가가 있으면 모든 것을 번역하십시오.
 

CL_DEVICE_PREFERRED_VECTOR_WIDTH_*의 Infa는 벡터의 최대 치수 또는 최적 치수를 나타냅니다.

CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE=2를 사용하면 double3 및 double4가 이미 속도가 느려지나요?

 
Roffild :

CL_DEVICE_PREFERRED_VECTOR_WIDTH_*의 Infa는 벡터의 최대 치수 또는 최적 치수를 나타냅니다.

CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE=2를 사용하면 double3 및 double4가 이미 속도가 느려지나요?

1. 최대한.

2. 많이 느려질 것 같지는 않지만 실행 속도는 증가하지 않을 것입니다.

 
MQL OpenCL은 원래 API에 대한 래퍼일 뿐입니다.
이 래퍼의 구현에 대한 답변과 설명을 알아야 합니다.

CLContextCreate() = clCreateCommandQueue(clCreateContextFromType(CL_DEVICE_TYPE_X)) ?
실제로 컨텍스트가 아닌 단일 장치에 대한 대기열입니까?

버퍼가 동기식으로 읽히거나 쓰여지나요? 아니면 비동기식으로 쓰입니까?
clEnqueue[읽기/쓰기]Buffer(인큐, 버퍼, CL_TRUE) - 여기에서 CL_TRUE 또는 CL_FALSE입니까?

부울 CLExecute(int 커널 ) = clEnqueueTask();
bool CLExecute(int 커널, uint work_dim, 작동...) = clEnqueueNDRangeKernel();
clEnqueueNativeKernel() - 구현되지 않았습니다.

CLExecute()는 즉시 제어를 반환합니까? 런타임에 차단되지 않습니까?
대기열에 설치하는 데 2-40ms가있는 것 같습니다 ...

이제 주요 질문:
언제 어떤 조건에서 clFinish()가 호출됩니까? 그리고 clFinish()가 없으면 대기열에 넣기가 어렵습니다.

그리고 MQL 도움말은 CL_MEM_*_HOST_PTR을 전혀 설명하지 않지만 존재합니다.

드디어 지표를 OpenCL 스타일로 바꿨습니다.
"M1에서 OHLC"로 M5에서 2013.01.09부터 2013.10.10까지 테스트 통과:
320초 - 전송 전
55초 - MQL5의 OpenCL 스타일 에뮬레이션:
 // подготовка данных общая и копия kernel на MQL5, а эмуляция через:
for ( int get_global_id = maxcount- 1 ; get_global_id>- 1 ; get_global_id--) NoCL( params ,m_result,get_global_id);
하지만 GPU에서의 출시는 저를 화나게 했습니다 :(
30초 이내에 테스트를 통과하고 싶었지만 CLBufferWrite에서 완전한 제동을 걸었습니다!

CL_MEM_*_HOST_PTR 없이 32%의 비디오 로딩 및 1710초 만에 테스트 통과
CL_MEM_ALLOC_HOST_PTR로 22%의 비디오 로딩 및 740초 만에 테스트 통과
CL_MEM_COPY_HOST_PTR 및 CL_MEM_USE_HOST_PTR 결과 CLExecute: 5109(ERR_OPENCL_EXECUTE)

그렇다면 올바른 데이터 공유 방법은 무엇일까요?

그리고 지금까지 테스터는 계산을 위해 CPU를 선택하지 않았습니다.

Vidyaha = ATI 라데온 HD 5850
프로세서 = AMD Phenom(tm) II X4 925 프로세서
 
Roffild :
CLContextCreate() = clCreateCommandQueue(clCreateContextFromType(CL_DEVICE_TYPE_X)) ?
실제로 컨텍스트가 아닌 단일 장치에 대한 대기열입니까?
예, 컨텍스트와 대기열은 장치별로 생성됩니다(연구에 따르면 opencl이 여러 장치에서 올바르게 작동하지 않는 것으로 나타났습니다).
버퍼가 동기식으로 읽히거나 쓰여지나요? 아니면 비동기식으로 쓰입니까?
clEnqueue[읽기/쓰기]Buffer(인큐, 버퍼, CL_TRUE) - 여기에서 CL_TRUE 또는 CL_FALSE입니까?
읽기와 쓰기는 동기식입니다.
부울 CLExecute(int 커널 ) = clEnqueueTask();
bool CLExecute(int 커널, uint work_dim, 작동...) = clEnqueueNDRangeKernel();
clEnqueueNativeKernel() - 구현되지 않았습니다.
CLExecute()는 즉시 제어를 반환합니까? 런타임에 차단되지 않습니까?

이제 주요 질문:
언제 어떤 조건에서 clFinish()가 호출됩니까? 그리고 clFinish()가 없으면 대기열에 넣기가 어렵습니다.
호출되지 않음, 메모리에서 읽기를 사용해야 합니다.
그리고 MQL 도움말은 CL_MEM_*_HOST_PTR을 전혀 설명하지 않지만 존재합니다.

드디어 지표를 OpenCL 스타일로 바꿨습니다.
"M1에서 OHLC"로 M5에서 2013.01.09부터 2013.10.10까지 테스트 통과:
320초 - 전송 전
55초 - MQL5의 OpenCL 스타일 에뮬레이션:
하지만 GPU에서의 출시는 저를 화나게 했습니다 :(
30ms 미만의 테스트 통과를 기대했지만 CLBufferWrite에서 완전한 제동을 걸었습니다!

CL_MEM_*_HOST_PTR 없이 32%의 비디오 로딩 및 1710초 만에 테스트 통과
CL_MEM_ALLOC_HOST_PTR로 22%의 비디오 로딩 및 740초 만에 테스트 통과
CL_MEM_COPY_HOST_PTR 및 CL_MEM_USE_HOST_PTR 결과 CLExecute: 5109(ERR_OPENCL_EXECUTE)

그렇다면 올바른 데이터 공유 방법은 무엇일까요?
CL_MEM_COPY_HOST_PTR 및 CL_MEM_USE_HOST_PTR 플래그는 현재 터미널에서 지원되지 않습니다(이 문제를 조사 중).
그리고 지금까지 테스터는 계산을 위해 CPU를 선택하지 않았습니다.
CPU 장치를 명시적으로 지정해 보셨습니까?
 

비동기 버퍼와 clFinish()를 제공하시겠습니까?

AMD CodeXL이 암시하는 속도가 느려지는 것은 동기식 기록이라는 가정이 있습니다.

"clEnqueueWriteBuffer: 불필요한 동기화. 쓰기 차단"

그리고 테스터에서 CPU는 숫자로도 선택되지 않습니다. 버그 #865549

 
어... GPU에서 OpenCL로 속도 향상에 대한 기사는 실제 작업이 아니기 때문에 동화로 판명되었습니다.

이번 달에 OpenCL을 정복하기 위해 수천 줄의 코드를 눈멀게 했습니다.

따라서 OpenCL을 디버그하려면 AMD CodeXL을 통해 실행하기 위해 C/C++에서 MQL의 기능을 에뮬레이트해야 했습니다.

2013.01.09부터 2013.10.10까지 M5에서 "OHLC on M1"으로 테스트를 통과한 결과를 반복하겠습니다.
320초 - 전송 전
55초 - MQL5의 OpenCL 스타일 에뮬레이션

"OpenCL 스타일"은 CopyHigh/CopyTime/CopyOpen/ ... 호출 횟수를 최소로 유지하고 이러한 함수가 호출된 후 배열을 처리할 코드의 양을 늘리는 것입니다.

그러나 이러한 계산은 OpenCL의 아름다운 기사에 충분하지 않습니다.

OpenCL 없이 테스트를 통과한 결과:
코어 1 EURUSD,M5: 55427ms 내에 생성된 1108637틱(55953바)(역사의 총 바 131439, 총 시간 55520ms)
55427ms / 1108637 틱 = 0.04999ms/tick - CPU에서 1틱 (OpenCL에서 실행은 이 시간을 초과해서는 안 됨)

하지만 내 C/C ++ 코드를 실행하고 AMD CodeXL을 통해 실행하여 이 데이터를 얻었습니다.
0.02000ms - 0.05000ms - GPU에서 내 커널 실행
0.35300ms - 500KB/s의 168바이트에 대해 clEnqueueWriteBuffer에 대한 한 번의 호출
0.35300ms - 9.500MB/s로 3.445KB에 대해 clEnqueueWriteBuffer에 대한 한 번 호출(평균 전송 시간은 동일함)

168바이트는 다음과 같습니다.
더블 오픈 [21] = {1.3668,1.361,1.3628,1.3662,1.366,164,166,136,136,136,12,16,12,16,16,16,16,16,16,16,16,16,16,136,136,136,136,136,136,136,136,136,136,136,1369,1369,1369,1369,1369,136927,1369,136927,1369,136927,1369,136927,1369,13679,136786 호 ,19,136786,136838};

그리고 21*168 배열의 크기 계산 오류로 인해 3.445KB를 받았지만 이마저도 전송시간에는 영향을 미치지 않았다.

결과적으로: 일반적인 MQL 패스(0.04999ms)보다 실제로 ~ 2배 빠른 0.02000ms로 커널을 최적화하더라도 모든 것은 GPU의 읽기/쓰기 속도 (0.35300ms - ~ MQL 계산보다 7배 느림!) .

OpenCL용 테스터에서 CPU가 선택되지 않아 빈 코어를 3개 더 사용할 수 없습니다...

추신
55초는 MQL 최적화의 한계가 아니라 지원이 없을 때만 OpenCL 에뮬레이션입니다 :)
Документация по MQL5: Доступ к таймсериям и индикаторам / CopyHigh
Документация по MQL5: Доступ к таймсериям и индикаторам / CopyHigh
  • www.mql5.com
Доступ к таймсериям и индикаторам / CopyHigh - Документация по MQL5
사유: