OpenCL: 실제 문제 - 페이지 7

 

1) Pragma는 지원 자체의 활성화가 아니라 컴파일 시간 지원 요구 사항입니다(생각하는 것처럼). 즉, 비디오 카드가 지원하는 경우 cl_khr_fp64가 이미 활성화되어 있습니다.

2) 그리고 실행 중에 배열의 크기가 변경되면? 물론 이 코드에서 구체적으로 빼는 것은 가능하지만 날씨가 좋아지는 것은 아니다.

AMD CodeXL에서 프로파일링을 수행했음을 즉시 알려드립니다.

3) 커널 자체의 계산 시간만 취하면 GPU에서 병렬화된 작업의 이득은 CPU 코어 수가 초과될 때입니다. 따라서 8개의 작업으로도 속도를 높일 수 있습니다.

4) Local을 구하는 공식은 나 스스로도 궁금한 것이 많다. 가장 큰 이득은 work_dim=1일 때 모든 비디오 코어에 작업을 분산했을 때였으며 이것이 UNITS입니다.

그리고 요소의 수를 나누어야 할 때 버퍼 크기를 전혀 나누는 이유는 무엇입니까? - 그게 바로 내가 한 일입니다.

Mathemat : 간단히 말해서: 코드는 무엇을 해야 합니까?

계산 준비 단계가 즉시 발생하지 않고 버퍼 전송에 많은 시간이 소요됨을 보여주기 위해 핫 태스크에서도 OpenCL을 사용 하는 것이 타당한지 의문을 제기합니다.

또한 테스터에서 CPU가 선택되지 않았음을 보여줍니다.

 
Roffild :

계산 준비 단계가 즉시 발생하지 않고 버퍼 전송에 많은 시간이 소요됨을 보여주기 위해 핫 태스크에서도 OpenCL을 사용 하는 것이 타당한지 의문을 제기합니다.

이것은 전혀 뉴스가 아닙니다. 글쎄, 즉, 이것에 대해 화를 내며 소리치는 것은 완전히 넌센스입니다. 그러나 측정은 완전히 다른 문제이며 실질적으로 유용할 수 있습니다.

또한 테스터에서 CPU가 선택되지 않았음을 보여줍니다.

이것은 정당화될 수도 있지만 재보험일 수도 있습니다. 어쨌든 테스트 프로세스 자체의 효율성을 보장하기 위해 의도적으로 수행되었음을 확신합니다. 보다 정확하게 최적화(다중 스레드이기 때문에). 여기에서 테스트와 최적화의 개념이 (정당 정치 수준에서) 명백하고 완전히 분리된 경우 포함을 달성할 가능성이 나타날 수 있습니다. 테스터를 사용하여 다른 부울 유형으로 정의하십시오. 적절한(공식적으로 다른) 소프트웨어 지원. (그것은 여러 면에서 좋을 것이고, 저는 이 분리/구별을 오랫동안 지지해 왔습니다. 다양한 최적화 및 테스트 실행 버튼까지.)

그런 다음 이론적으로 테스트 중에 CPU 선택을 허용하고 최적화 중에 비활성화할 수 있습니다(정확함).

 
Roffild : 1) Pragma는 지원 자체를 활성화하는 것이 아니라 컴파일 시 지원을 요구하는 것입니다. 즉, 비디오 카드가 지원하는 경우 cl_khr_fp64가 이미 활성화되어 있습니다.

예, 프래그마를 너무 많이 사용했습니다. vidyaha 작업을 계속하고 다른 사람에게 코드를 전달하지 않아도 문제가 되지 않습니다. 그러나 누군가가 Barts 카드(예: 6870)에서 그것을 읽고 싶다면 문제가 있을 것입니다. 커널 코드는 오류를 표시하지 않고 실행을 시도합니다.

4) Local을 구하는 공식은 나 스스로도 궁금한 것이 많다. 가장 큰 이득은 work_dim=1일 때 모든 비디오 코어에 작업을 분산했을 때였으며 이것이 UNITS입니다.

필요하지 않습니다. 종종 커널 자체에서 작업을 늘리는 것이 훨씬 더 유용합니다. 이는 데이터 전송과 관련된 오버헤드를 평준화하기 위한 것입니다.

그리고 당신의 UNITS는 SIMD 엔진의 숫자일 뿐입니다. 문서 에 따르면,

local_work_size[] 는 프로그램의 지정된 OpenCL 커널이 수행할 작업의 하위 집합을 지정합니다. 그 차원은 work_items[] 의 차원과 같으며 작업의 공통 하위 집합 을 분할 잔여 없이 더 작은 하위 집합으로 절단할 수 있습니다. 사실, local_work_size[] 배열의 크기는 전역 work_items[] 작업 집합이 더 작은 하위 집합으로 잘리는 방식으로 선택해야 합니다 . 이 예에서 local_work_size[3]={10, 10, 10} work_items[40, 100, 320] 이 어떤 잔류물도 남기지 않고 local_items[10, 10, 10] 배열 에서 어셈블될 수 있기 때문에 수행 됩니다.

SIMD 엔진의 수는 엄격하게 하드웨어 상수이며 전역 작업을 완전히 나눌 의무가 전혀 없습니다.

그러나 먼저 전역 작업 자체를 올바르게 평가해야 합니다.

테스터의 CPU에 관해서는 - 나는 확신합니다.

 
MetaDriver :

이것은 전혀 뉴스가 아닙니다. 글쎄, 즉, 이것에 대해 화를 내며 소리치는 것은 완전히 넌센스입니다. 그러나 측정은 완전히 다른 문제이며 실질적으로 유용할 수 있습니다.

하지만 어떤 이유에서인지 이러한 측정값을 처리해야 했습니다... "전송 지연이 있습니다."라고 읽으면 얼마나 큰지 상상조차 할 수 없습니다.

Mathemat : 그리고 당신의 UNITS는 SIMD 엔진의 숫자일 뿐입니다. 문서 에 따르면,

SIMD 엔진의 수는 엄격하게 하드웨어 상수이며 전역 작업을 완전히 나눌 의무가 전혀 없습니다.

공식 문서를 더 잘 사용합시다.

CL_DEVICE_MAX_COMPUTE_UNITS cl_uint OpenCL 장치의 병렬 컴퓨팅 장치 수입니다. 작업 그룹은 단일 계산 단위에서 실행됩니다. 최소값은 1입니다.
local_work_size
커널이 지정한 커널을 실행할 작업 그룹(작업 그룹의 크기라고도 함)을 구성하는 작업 항목의 수를 설명하는 work_dim 부호 없는 값의 배열을 가리킵니다.
따라서 내 결론은 정확하고 AMD CodeXL 에서 실행하여 확인되었습니다.
 

요점은 다릅니다. 단위를 최소한 배럴이라고 부르지 만 사실은 그대로입니다. 코드의 단위는 전역 작업을 완전히 나누지 않습니다(분할하지 않습니다: 240/28은 정수가 아닙니다. 18). 이것은 조인트입니다.

그리고 두 번째: 지금 여기에서 MQL5용 OpenCL로 작업하고 있습니다(잘못된 얘기지만 이해했습니다). 이것은 여전히 Khronos의 OpenCL과 다른 OpenCL입니다.

추신 : 하이퍼 링크를 만들지 않았으며 자체적으로 밝혀졌습니다. :)

Roffild :
CL_DEVICE_MAX_COMPUTE_UNITS cl_uint OpenCL 장치의 병렬 컴퓨팅 장치 수입니다. 작업 그룹은 단일 계산 단위에서 실행됩니다. 최소값은 1입니다.

"계산 단위"가 무엇인지 다른 출처에서 읽으십시오.

그건 그렇고, 여기에 내 두 번째 기사의 표가 있습니다. 이러한 모든 계산 단위(18), 스트림 코어(288), 처리 요소(1440), 최대 웨이브프론트/GPU(496) 및 작업 항목/GPU(31744)를 이해했다면 좋을 것입니다. 아직 알아내지 못했습니다.


 
Mathemat :

요점은 다릅니다. 단위를 최소한 배럴이라고 부르지 만 사실은 그대로입니다. 코드의 단위는 전역 작업을 완전히 나누지 않습니다(분할하지 않습니다: 240/28은 정수가 아닙니다. 18). 이것은 조인트입니다.

그렇다면 왜 240바이트 수를 기준으로 삼았습니까? double을 바이트로 자르기로 결정했습니까? 당신은 할 수 있고 할 수 있지만 vidyaha는 할 수 없습니다. 따라서 240/8 = 30 두 배입니다.

240바이트는 30배의 전체 버퍼 크기입니다.

그리고 "정수 제수 선택"은 공식 문서 의 권장 사항일 뿐입니다 . 그리고 이 권장 사항은 완벽하게 작동하지 않습니다.

그리고 UNITS에 대해 - 이것은 제 개그가 아니라 OpenCL 포럼의 조언입니다. 테스트 해보니 최고속도 나오네요...

수학 :

그리고 두 번째: 지금 여기에서 MQL5용 OpenCL로 작업하고 있습니다(잘못된 얘기지만 이해했습니다). 이것은 여전히 Khronos의 OpenCL과 다른 OpenCL입니다.

그리고 "기타"는 무엇입니까?

자신의 구현과 간단한 래퍼를 혼동하고 있습니다. OpenCL MQL은 Khronos OpenCL API에 대한 래퍼일 뿐입니다. OpenCL MQL과 Khronos의 차이점에 대해.

 
Mathemat : 그건 그렇고, 여기 내 두 번째 기사의 표가 있습니다. 이러한 모든 계산 단위(18), 스트림 코어(288), 처리 요소(1440), 최대 웨이브프론트/GPU(496) 및 작업 항목/GPU(31744)를 이해했다면 좋을 것입니다. 아직 알아내지 못했습니다.

계산 단위는 실행할 동시 작업 수입니다.

max wavefronts/GPU(496) 및 work-items/GPU(31744)는 실행 대기열입니다.

AMD CodeXL은 이미 마침내 zayuzat - 그는 이 모든 질문에 답합니다.

 
Roffild :

계산 단위는 실행할 동시 작업 수입니다.

max wavefronts/GPU(496) 및 work-items/GPU(31744)는 실행 대기열입니다.

AMD CodeXL은 이미 마침내 zayuzat - 그는 이 모든 질문에 답합니다.

이해가 안되는 부분이 있을 수 있습니다. 죄송합니다. 하지만 당신은 개인적으로 Alexei를 알고 있습니까? Aleksey 동지는 겸손하며 "찌르기"에 반응하지 않을 수 있습니다. 하지만 뭔가의 측면에서 어떻게 든 그렇지 않은 ..... 그레이하운드처럼 당신이 말하는 모든 사람보다 똑똑합니까? 똑똑한 것이 죄가 아니고, 형제들 사이에서 이것을 자랑스럽게 생각하는 것은 부끄러운 일이지만...

 

나는 단순한 친구이며 요점에 대답합니다.

OpenCL을 정말로 이해하고 싶고 가정만 하는 것이 아니라 AMD CodeXL을 설치하고 C/C ++로 자체 래퍼를 만들어야 합니다.

내 래퍼를 게시할 수 있지만 C/C++ 연습 부족으로 인해 일부 비논리적인 줄이 있습니다.

 
Roffild : 그럼 왜 바이트 수를 240으로 하였습니까? double을 바이트로 자르기로 결정했습니까? 당신은 할 수 있고 할 수 있지만 vidyaha는 할 수 없습니다. 따라서 240/8 = 30배입니다.

240바이트는 30배의 전체 버퍼 크기입니다.

글쎄, 당신의 코드를보십시오 :

 uint units = ( uint ) CLGetInfoInteger (hcontext, CL_DEVICE_MAX_COMPUTE_UNITS );
uint global_work_offset[] = { 0 };
uint global_work_size[ 1 ];
uint local_work_size[ 1 ];
global_work_size[ 0 ] = ArraySize (price);
Print( "Глобальная задача = ", global_work_size[ 0 ] );  /// Это я добавил, вышло 240. Но это и так легко подсчитать: 30*double = 240
local_work_size[ 0 ] = global_work_size[ 0 ] / units;

그런 다음 마지막 줄에서 240을 18로 나눕니다(이것은 지도의 단위입니다).

그리고 "정수 제수 선택"은 공식 문서 의 권장 사항일 뿐입니다 . 그리고 이 권장 사항은 완벽하게 작동하지 않습니다.

우리는 MQL5 OpenCL로 작업합니다. 저는 우리 사이트의 문서 섹션에 중점을 둡니다. 물론 크로노스도 봅니다.

그리고 UNITS에 대해 - 이것은 제 개그가 아니라 OpenCL 포럼의 조언입니다. 테스트 해보니 최고속도 나오네요...

글쎄, 나는 다른 매개 변수로 최대 값을 얻었습니다. 그리고 뭐?

진정하자. GPU 플라이에서 동시에 실행되는 18개의 작업은 4-5개의 CPU 스레드에서 수행할 수 있는 최대값입니다. 그리고 x86 에뮬레이션의 CPU는 훨씬 더 많은 스레드를 구성할 수 있습니다. 적어도 인텔이라면 말이다. 내 이전 Pentium G840(2코어)은 두 장치에서 약 70배의 가속을 제공했습니다! 나는 나의 현재 ... 상대적으로 말하자면 i7이 하고 있는 것에 대해 말하는 것이 아닙니다.

병렬 작업(Ocl에 대한 첫 번째 분기의 MetaDriver 스크립트 참조)을 통해 GPU에서 최대 1000개 이상의 속도 향상을 달성할 수 있습니다(MQL5의 CPU에서 1개 스레드에서 실행하는 것과 비교). 찾을 수 없으면 버릴 수 있습니다. 지도에서 테스트해 보세요.

OpenCL을 정말로 이해하고 싶고 가정만 하는 것이 아니라 AMD CodeXL을 설치하고 C/C ++로 자체 래퍼를 만들어야 합니다.

알겠습니다. 감사합니다.