OpenCL: sfide reali - pagina 6

 
Mathemat: Non l'ho ancora controllato nel tester.

Allora perché hai postato delle sciocchezze senza controllo?

Forse sono l'unico che ha provato OpenCL nel tester dopo tutto... provato...

 
Roffild:

Allora perché ha postato delle sciocchezze non verificate?

Probabilmente sono l'unico che ha usato OpenCL nel tester dopo tutto... provato...

Non è una sciocchezza, è una richiesta soddisfatta.

Ancora una volta, scrivete a servicedesk e giustificate ciò che volete. Se non riesci a giustificarlo, è un tuo problema.

Al momento di scrivere questi articoli, il discorso sull'uso di OpenCL nel tester non era ancora iniziato sul serio. La domanda si riferisce proprio a quel momento.

Sei tu che dovresti accendere il cervello, perché 0,35300 ms si riferisce a clEnqueue[Read/Write]Buffer() e non all'accesso globale alla memoria all'interno del kernel.
Questo comando non è presente nell'implementazione di OpenCL per MQL5. Di cosa stai parlando?
 
Roffild:

Ripercorri i miei post.

Il criterio principale: l'esecuzione del codice MQL in "stile OpenCL" per 1 tick deve superare il tempo = Number_Buffers * 0.35300 ms

Per scoprire la velocità dell'algoritmo in MQL con precisione al microsecondo (1000 microsecondi = 1 millisecondo) si dovrà eseguire più volte in tester e Total_Time / Number_of_Ticks (il mio post in alto).

Se non fosse per il ritardo del buffer, il mio codice passerebbe il test in ~30 secondi - che è ~2 volte più veloce del MQL "stile OpenCL" (55 secondi) e ~11 volte più veloce del codice normale (320 secondi).

Quali altri criteri ci sono?

Non ti sto chiedendo di rileggere tutti i miei post sul forum di OpnCL. :) A tutti i criteri di base sono descritti e discussi lì.

Il criterio principale è il rapporto t_alg/t_mem dove t_alg- tempo ottimizzato di calcolo dell 'algoritmo del kernel e t_mem- tempo di accesso alla memoria cancellata (*). Più lungo è questo criterio, migliori sono le prospettive di accelerazione tramite OpenCL. In altre parole, più difficili sono i calcoli e meno trasferimenti di array da e verso il dispositivo, migliori sono le prospettive.

(*) memoria remota = tutti i tipi di memoria "non di registro" (la memoria di registro è molto veloce), ad esempio (1) la memoria globale del dispositivo è molto più lenta della memoria di registro ma molto più veloce di (2) la memoria esterna al dispositivo (RAM della CPU).

OpenCL: от наивного кодирования - к более осмысленному
OpenCL: от наивного кодирования - к более осмысленному
  • 2012.06.05
  • Sceptic Philozoff
  • www.mql5.com
В данной статье продемонстрированы некоторые возможности оптимизации, открывающиеся при хотя бы поверхностном учете особенностей "железа", на котором исполняется кернел. Полученные цифры весьма далеки от предельных, но даже они показывают, что при том наборе возможностей, который имеется здесь и сейчас (OpenCL API в реализации разработчиков терминала не позволяет контролировать некоторые важные для оптимизации параметры - - в частности, размер локальной группы), выигрыш в производительности в сравнении с исполнением хостовой программы очень существенен.
 
Mathemat:

Questa non è una sciocchezza, ma un'applicazione soddisfatta.

Ancora una volta, scrivete a servicedesk e giustificate ciò che volete. Se non riesci a giustificarlo, è un tuo problema.

Ancora una volta: bug #865549 dal 2013.10.17 23:17 e gli sviluppatori sono notificati, ma è improbabile che risolvano qualcosa. Probabilmente questa limitazione qualcuno l'ha aggiunta di proposito per non sospendere l'intero processore durante l'ottimizzazione.

Ma gli articoli non dicono una parola al riguardo!

Matematica:
È il momento di accendere il cervello perché 0,35300 ms si riferisce a clEnqueue[Read/Write]Buffer() e non all'accesso globale alla memoria all'interno del kernel.

Questo comando non è presente nell'implementazione di OpenCL per MQL5. Di cosa stai parlando?

Eh... E stai anche sparando articoli su OpenCL...

Tanto per sapere, clEnqueueReadBuffer = CLBufferRead e clEnqueueWriteBuffer = CLBufferWrite sono chiamati in modo sincrono.

L'apprendimento inizia qui

MetaDriver: Il criterio principale è il rapporto t_alg/t_mem, dove t_alg è il tempo di calcolo algoritmicamente ottimizzato dell'algoritmo del kernel e t_mem è il tempo di accesso alla memoria cancellata (*). In altre parole, più "pesanti" sono i calcoli e minori sono i trasferimenti di array da e verso il dispositivo, maggiore è il potenziale di accelerazione con OpenCL.
Questo è un criterio per ottimizzare solo l'esecuzione. Non c'erano numeri approssimativi sulla velocità di trasferimento dei buffer stessi prima dei miei post.
 

Gente, prima di discutere ulteriormente, pensate ai tre post che iniziano qui e in particolare a

mql5: In questo particolare esempio, il vantaggio di usare OpenCL è consumato dall'overhead della copia del buffer.


Perché tu sei concentrato sull'ottimizzazione del kernel stesso, mentre i miei post riguardano i buffer.

 
Roffild: Tanto per sapere: clEnqueueReadBuffer = CLBufferRead e clEnqueueWriteBuffer = CLBufferWrite e sono chiamati in modo sincrono.

So da molto tempo che l'implementazione di OpenCL per MQL5 è solo un wrapper sopra la vera API. A proposito, ho scritto nel mio secondo articolo che manca la possibilità di impostare la dimensione del gruppo di lavoro. Ho fatto una richiesta a servicedesk, e l'hanno fatto dopo un po'.

So anche che CLBuffer[Read/Write] è simile a clEnqueue[Read/Write]Buffer, ma queste funzioni non sono affatto identiche: hanno sintassi diverse.

Ma non capisco perché continuate a parlare di funzioni clEnqueueXXX che non sono presenti in OpenCL per MQL5.

Cercherò di capire cosa vuoi.

Roffild:

È il momento di accendere il cervello perché 0,35300 ms si riferisce a clEnqueue[Read/Write]Buffer() e non all'accesso alla memoria globale all'interno del kernel.

Il secondo può essere risolto ottimizzando il kernel stesso, mentre il primo è un limite di ferro.

Ok. Contro chi ha un reclamo? Il produttore della scheda grafica?
 
Mathemat: So anche che CLBuffer[Read/Write] è analogo a clEnqueue[Read/Write]Buffer ma queste funzioni non sono affatto identiche: hanno sintassi diverse.

Ma non capisco perché continuate a parlare di funzioni clEnqueueXXX che non esistono in OpenCL per MQL5.

Non c'è differenza. Probabilmente esiste un tale involucro:

template<typename T>
cl_int BufferWrite(cl_mem buffer, const T *ptr)
{
        size_t bufsize;
        errcode = clGetMemObjectInfo(buffer, CL_MEM_SIZE, sizeof(bufsize), &bufsize, 0);
        return (errcode = clEnqueueWriteBuffer(enqueue, buffer, CL_TRUE, 0, bufsize, ptr, NULL, NULL, NULL));
}
template<typename T>
cl_int BufferRead(cl_mem buffer, T *ptr)
{
        size_t bufsize;
        errcode = clGetMemObjectInfo(buffer, CL_MEM_SIZE, sizeof(bufsize), &bufsize, 0);
        return (errcode = clEnqueueReadBuffer(enqueue, buffer, CL_TRUE, 0, bufsize, ptr, NULL, NULL, NULL));
}

Quindi non c'è nemmeno bisogno di elaborare la sintassi. Il fatto che il 3° argomento = CL_TRUE è già stato confermato.

Matematica:

Il secondo può essere risolto ottimizzando il kernel stesso, mentre il primo è un vincolo di ferro e il cervello non aiuta.
Ok. Contro chi ha un reclamo? Il produttore della scheda video?

La lamentela è agli autori degli articoli che non ci sono dati pratici su questa limitazione più importante! (Non c'era, finché non l'ho testato).

 
Roffild:

La lamentela è diretta agli autori dell'articolo, che non ci sono dati pratici su questo limite più importante! (Non c'era, finché non l'ho testato).

Non leggete più articoli e non vi lamenterete più. ;)

--

Perché te la prendi con me? Come puoi citare dati sconosciuti in un articolo? Il ritardo nel trasferimento dei dati da/verso un dispositivo è enorme e deve essere preso in considerazione? Le cifre specifiche dipendono dall'hardware specifico. Beh, l'hai testato su te stesso e ben fatto. A volte le persone (me compreso) preparano del codice di prova per stimare le capacità e i limiti di diversi hardware. Chiedono ad altre persone di condividere i risultati, la gente spesso lo fa (complimenti a loro per questo), allo stesso tempo tutti possono vedere le statistiche e cosa funziona in quali combinazioni. Poi qualcuno ricompra l'hardware o cambia l'approccio alla scrittura del codice con i risultati in mente. Cosa vuoi? Beh, scrivi un reclamo a Sportloto, forse questo farà funzionare il tuo codice più velocemente...

:)

 

In realtà ho già finito tutto su https://www.mql5.com/ru/forum/13715/page5#comment_646513, ma gli stessi autori degli articoli volevano dimostrare qualcos'altro.

Non ci sono informazioni specifiche e molto importanti nei tuoi articoli, quindi non sono finiti e descrivono compiti irrealistici.

Si può non aggiungere informazioni agli articoli, ma è sciocco far finta che queste cifre particolari non significhino nulla.

OpenCL: реальные задачи
OpenCL: реальные задачи
  • www.mql5.com
Так что же может дать OpenCL трейдерам?
 

Non capisco il significato nascosto dello script/consiglio che hai postato, Roffild. Il codice è, a dir poco, incomprensibile.

- Dov'è il pragma cl_khr_fp64? Vi serve quando calcolate con il doppio nel kernel.

- Perché c'è questo pezzo di codice nella funzione OnTick(), che può essere messo nell'inizializzazione iniziale calcolando una volta?

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);
local_work_size[0] = global_work_size[0] / units;

- Perché la dimensione del compito globale è uguale a 240 byte? Dovrebbe essere molto più grande per ottenere qualche beneficio da OpenCL. Beh, dovrebbe essere almeno un milione di volte più grande se si può giudicare solo a occhio.

- Perché un compito globale dovrebbe dividere per il numero di unità per ottenere la dimensione di uno locale? Sia la CPU che la GPU permettono di dividere un compito globale in un numero molto più grande di sottocompiti. E le unità nel vostro caso sono solo un numero di motori SIMD.

Diciamo che ho, per esempio, il numero di unità nella mia scheda video è 28 (Radeon HD7950). Ma questo numero non divide esattamente 240. Significa che una parte significativa dei calcoli può essere non parallela.

Il numero di shader che ho è 1792. Il tuo è 1440. Questo è più o meno il numero che è meglio dividere il compito globale, per caricare correttamente la mappa. Ma dovrete calcolare la corretta dimensione globale del compito. (Ed è meglio non dividere, ma moltiplicare).

E ciò che la vostra mappa conta per tutto questo tempo non è affatto chiaro.

In breve: cosa dovrebbe fare il vostro codice?