OpenCL: sfide reali - pagina 7

 

1) I pragmi sono un requisito per il supporto a tempo di compilazione, non l'attivazione del supporto stesso (come sembri pensare). Quindi cl_khr_fp64 è già coinvolto se il vostro visore lo supporta.

2) E se la dimensione dell'array cambia a runtime? Certo, può essere fatto in questo particolare codice, ma non migliorerà la situazione.

Lasciate che vi dica subito che stavo profilando in AMD CodeXL:

3) Se prendiamo solo il tempo di calcolo del kernel stesso, qualsiasi compito parallelizzato sulla GPU guadagnerà beneficio utilizzando più core sulla CPU. Quindi anche 8 compiti sono sufficienti per accelerare le cose.

4) Io stesso ho molte domande sulla formula di calcolo Local. Il guadagno maggiore è avvenuto quando a work_dim=1 stavo distribuendo i compiti su tutti i core del widget e questo è UNITS.

E perché si divide la dimensione del buffer in generale, quando si dovrebbe dividere il numero dei suoi elementi? - cosa che in effetti ho fatto.

Mathemat: In breve: cosa deve fare il vostro codice?

Per dimostrare che la fase di preparazione ai calcoli non è istantanea e il trasferimento del buffer richiede molto tempo; mette in dubbio la praticabilità dell'uso di OpenCL anche per compiti alimentati.

Mostra anche che la CPU non è selezionata nel tester.

 
Roffild:

Mostrando che la fase di preparazione per i calcoli non è istantanea e il trasferimento del buffer richiede molto tempo, il che mette in discussione la praticabilità dell'uso di OpenCL anche per i compiti hyped up.

Cioè, è abbastanza sciocco gridarlo; misurarlo, d'altra parte, è un'altra cosa; può essere praticamente utile.

Mostra anche che la CPU non è selezionata nel tester.

Forse è giustificato, ma forse è un eccesso di assicurazione. Comunque, sono sicuro che è stato fatto consapevolmente per garantire l'efficienza del processo di test stesso. Più precisamente, l'ottimizzazione (dal momento che è multi-threaded). Qui le possibilità di inclusione possono apparire se la nozione di test e ottimizzazione sono chiaramente e completamente separati (a livello di politica di partito), cioè se li definiamo come diversi tipi logici di utilizzo del tester. Con corrispondente supporto software (ufficialmente diverso). (Questo sarebbe buono in molti modi, e io sono un sostenitore di lunga data di tale separazione/distinzione. Fino a pulsanti diversi per iniziare l'ottimizzazione e il test).

Teoricamente, la selezione della CPU potrebbe essere consentita durante i test e non consentita durante l'ottimizzazione (questo è corretto).

 
Roffild: 1) I pragmi sono un requisito del supporto a tempo di compilazione, non un'attivazione del supporto stesso (come sembri pensare). Cioè, cl_khr_fp64 è già coinvolto se le viscere lo supportano.

Sì, ho esagerato con il pragma. Se continuerete a lavorare sul vostro widget e non passerete il codice a nessun altro, nessun problema. Ma se qualcuno vuole leggerlo sulla scheda Barts (per esempio, 6870), ci saranno problemi. Il codice del kernel cercherà di essere eseguito senza mostrare errori.

4) Anch'io ho molte domande sulla formula per calcolare Local. Il maggior guadagno è stato quando work_dim=1 distribuisce i compiti su tutti i core del widget, che è UNITS.

Non necessariamente. Spesso è molto più utile aumentare il lavoro nel kernel stesso. È per pareggiare l'overhead associato al trasferimento dei dati.

E la vostra UNITS è solo un numero di motori SIMD. Secondo la documentazione,

local_work_size[] imposta un sottoinsieme di compiti da eseguire dal kernel del programma OpenCL specificato . La sua dimensione è uguale a work_items[]e permette di tagliare il sottoinsieme totale dei compiti in sottoinsiemi più piccoli senza residui di divisione . Infatti, la dimensione dell'arraylocal_work_size[] deve essere scelta in modo che l'insieme globale dei compiti work_items[] sia suddiviso in sottoinsiemi più piccoli. In questo esempio ,local_work_size[3]={10, 10, 10} andrà bene , poichéwork_items[40, 100, 320] può essere assemblato dall'array local_items[10, 10, 10] senza alcun residuo .

Il numero di motori SIMD è una costante strettamente hardware che non deve affatto dividere il compito globale.

Ma prima è necessario valutare correttamente il problema globale stesso.

Riguardo alla CPU nel tester - vedo, sono convinto.

 
MetaDriver:

Questo non è assolutamente niente di nuovo. Voglio dire, è sciocco gridarlo, ma misurarlo è un'altra cosa; può essere utile nella pratica.

A parte il fatto che per qualche motivo ho dovuto prendere queste misure... Quando leggete "c'è un ritardo di trasmissione" non avete idea di quanto sia grande.

Mathemat: E la vostra UNITS è solo un numero di motori SIMD. Secondo la documentazione,

Il numero di motori SIMD è una costante strettamente hardware, che non deve affatto dividere il compito globale.

Usiamo meglio la documentazione ufficiale:

CL_DEVICE_MAX_COMPUTE_UNITS cl_uint Il numero di unità di calcolo parallele sul dispositivo OpenCL. Un gruppo di lavoro viene eseguito su una singola unità di calcolo. Il valore minimo è 1.
dimensione_lavoro_locale.
Punta a un array di valori senza segno work_dim che descrivono il numero di elementi di lavoro che compongono un gruppo di lavoro (indicato anche come la dimensione del gruppo di lavoro) che eseguirà il kernel specificato dal kernel.
Quindi le mie conclusioni sono corrette e confermate da AMD CodeXL run
 

Il punto è diverso. Chiama i tuoi barili di unità, ma resta il fatto che le unità nel tuo codice non dividono il compito globale intero (il mio certamente no: 240/28 non è intero; anche il tuo, visto che hai unità=18). Questo è un bug.

E in secondo luogo, qui e ora si sta lavorando con OpenCL per MQL5 (beh, non è giusto, ma mi avete preso); che, dopo tutto, è un OpenCL diverso da quello di Khronos.

P.S. Non ho creato il collegamento ipertestuale; l'ho solo ottenuto da solo :)

Roffild:
CL_DEVICE_MAX_COMPUTE_UNITS cl_uint Il numero di unità di calcolo parallele sul dispositivo OpenCL. Un gruppo di lavoro viene eseguito su una singola unità di calcolo. Il valore minimo è 1.

Vedere altre fonti per la definizione di "unità di calcolo".

A proposito, ecco una tabella del mio secondo articolo. Sarebbe bello se capiste tutte queste unità di calcolo (18), stream core (288), elementi di elaborazione (1440), max wavefronts/GPU (496) e work-items/GPU (31744). Non l'ho ancora capito.


 
Mathemat:

Il punto è diverso. Chiama i tuoi barili di unità, ma resta il fatto che le unità nel tuo codice non dividono il compito globale intero (il mio certamente no: 240/28 non è intero; anche il tuo, visto che hai unità=18). Questo è un problema tecnico.

Allora perché ha basato il numero di byte su 240? Tu potresti essere in grado di farlo, ma la scheda grafica no. Quindi 240/8 = 30 doppi.

240 byte è la dimensione dell'intero buffer di 30 doppi.

E "scegliere un divisore intero" è solo una raccomandazione della documentazione ufficiale. E questa raccomandazione non funziona perfettamente.

E quello che riguarda UNITS non è mio; è solo un consiglio dai forum OpenCL. L'ho testato e ho ottenuto la massima velocità...

Matematica:

E la seconda cosa: qui e ora state lavorando con OpenCL per MQL5 (beh, non è giusto, ma mi avete preso) dove è, dopo tutto, un OpenCL diverso da quello di Khronos.

E qual è l'"altro"?

Stai confondendo le implementazioni proprietarie e i semplici wrapper. OpenCL MQL è solo un wrapper su Khronos OpenCL API. Sulla differenza tra OpenCL MQL e Khronos.

 
Mathemat: A proposito, ecco la tabella del mio secondo articolo. Sarebbe bello se capiste tutte queste unità di calcolo (18), stream core (288), elementi di elaborazione (1440), max wavefronts/GPU (496) e work-items/GPU (31744). Non l'ho ancora capito.

unità di calcolo è il numero di compiti simultanei che vengono eseguiti.

max wavefronts/GPU (496) e work-items/GPU (31744) sono la coda da eseguire.

AMD CodeXL ha già una risposta a tutte queste domande.

 
Roffild:

unità di calcolo è il numero di compiti simultanei che vengono eseguiti.

max wavefronts/GPU (496) e work-items/GPU (31744) sono la coda di esecuzione.

AMD CodeXL può aiutarvi finalmente - risponde a tutte queste domande.

Forse non capisco qualcosa, scusi, ma lei conosce personalmente Alexey? Ma dal lato non sembra..... parli in modo troppo sfacciato, più intelligente degli altri? Essere intelligenti non è un peccato, vantarsene tra fratelli in spirito è però vergognoso...

 

Sono un tipo semplice e rispondo al punto.

Se volete davvero capire OpenCL e non solo supporre, dovrete mettere AMD CodeXL e creare il vostro wrapper C/C++.

Posso postare il mio wrapper, ma ha alcune linee illogiche dovute alla mia mancanza di pratica in C/C++.

 
Roffild: Allora perché ha preso 240 byte come numero di base? Tu potresti essere in grado di farlo, ma la scheda video no. Quindi 240/8 = 30 doppi.

240 byte è la dimensione dell'intero buffer di 30 doppi.

Guardate il vostro codice:

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;

Inoltre, nell'ultima riga, voi stessi dividete 240 per 18 (queste sono unità per la vostra mappa).

E "prendere tutto il divisorio" è solo una raccomandazione della documentazione ufficiale. E questa raccomandazione non funziona perfettamente.

Stiamo lavorando con MQL5 OpenCL. Mi riferisco alla documentazione sul nostro sito web. Naturalmente, sto anche guardando Khronos.

E per quanto riguarda UNITS, non sono parole mie, ma alcuni consigli dai forum OpenCL. L'ho testato e ho ottenuto la velocità massima...

Bene, ho ottenuto la massima velocità con diversi parametri. Quindi?

Diamo solo un'idea approssimativa. 18 compiti in esecuzione simultanea su GPU vola è il massimo che può essere fatto su 4-5 stringhe di CPU. E una CPU su emulazione x86 può organizzare molti più thread. Almeno se è Intel. Il mio precedente Pentium G840 (2 core) dava un'accelerazione di circa 70x - su due unità! Per non parlare di quello che il mio attuale... i7, per così dire.

Un compito ben parcellizzato (date un'occhiata agli script MetaDriver del primo ramo ocl) permette di raggiungere velocità fino a 1000 o più su GPU (in confronto a 1 thread su CPU in MQL5). Se non riesci a trovarlo - posso scaricarlo per te per provarlo sulla tua carta.

Se volete davvero capire OpenCL e non solo indovinarlo, dovrete mettere AMD CodeXL e creare il vostro wrapper C/C++.

OK, gli darò un'occhiata, grazie.