2010-06-30 13 views
9

Salve: le dimensioni del lavoro globale (dimensioni) devono essere multiple di dimensioni del gruppo di lavoro (dimensioni) in OpenCL?Le dimensioni del lavoro globale devono essere multiple della dimensione del gruppo di lavoro in OpenCL?

In tal caso, esiste un metodo standard per gestire le matrici non un multiplo delle dimensioni del gruppo di lavoro? Posso pensare a due possibilità:

Impostare dinamicamente la dimensione delle dimensioni del gruppo di lavoro su un fattore delle dimensioni di lavoro globali. (ciò comporterebbe il sovraccarico di trovare un fattore e probabilmente impostare il gruppo di lavoro su una dimensione non ottimale.)

Aumentare le dimensioni del lavoro globale per essere il multiplo più vicino delle dimensioni del gruppo di lavoro, mantenendo tutti gli input e i buffer di output sono gli stessi ma controllano i limiti nel kernel per evitare il segfaulting, ovvero non fare nulla sugli elementi di lavoro fuori dal limite dell'output desiderato. (Questo sembra il modo migliore.)

La seconda via avrebbe funzionato? C'è un modo migliore? (O non è necessario perché le dimensioni del gruppo di lavoro non devono necessariamente dividere le dimensioni del lavoro globale?)

Grazie!

+0

Interessante che tu stia facendo questa domanda, come stavo chiedendo io stesso. La mia prima ipotesi è che tu mantenga una dimensione fissa del gruppo di lavoro e maneggi fuori da un ramo if. – Stringer

risposta

7

Thx per il collegamento Ciad. Ma in realtà, se si legge il:

Se non viene specificato local_work_size, i valori specificati nella global_work_size [0], ... global_work_size [work_dim - 1] deve essere uniformemente divisibile per i corrispondenti valori specificati nella local_work_size [0 ], ... local_work_size [work_dim - 1].

Quindi SÌ, la dimensione del lavoro locale deve essere un multiplo delle dimensioni del lavoro globale.

Penso anche che assegnare le dimensioni del lavoro globale al multiplo più vicino e fare attenzione ai limiti dovrebbe funzionare, posterò un commento quando mi metto a provarlo.

1

Secondo lo standard non deve essere da quello che ho visto. Penso che lo gestirò con un ramo, ma non so esattamente quale tipo di operazione a matrice stai facendo.

http://www.khronos.org/registry/cl/specs/opencl-1.1.pdf#page=131

global_work_size punti a una matrice di work_dim valori senza segno che descrivono il numero di globali da lavoro articoli in work_dim dimensioni che eseguirà la funzione kernel. Il numero totale di articoli di lavoro globali è calcolato come global_work_size[0] * ... * global_work_size[work_dim – 1].

I valori specificati global_work_size + corrispondente valori specificati in global_work_offset non può superare l'intervallo in sizeof(size_t) per il dispositivo sul quale l'esecuzione kernel sarà accodato. Il sizeof(size_t) per un dispositivo può essere determinato utilizzando CL_DEVICE_ADDRESS_BITS nella tabella 4.3. Se, per esempio, CL_DEVICE_ADDRESS_BITS = 32, cioè Il dispositivo utilizza un indirizzo spazio 32 bit, size_t è un 32 bit senza segno interi e valori global_work_size deve essere nell'intervallo 1 .. 2^32 - 1 I valori al di fuori di questo intervallo restituiscono un errore .

1

Questo sembra essere un vecchio post, ma permettimi di aggiornare questo post con alcune nuove informazioni. Si spera, potrebbe aiutare qualcun altro.

fa Globale Work Size (Dimensioni) devono essere multipli del gruppo di lavoro Size (Dimensioni) in OpenCL?

Risposta: True fino OpenCL 2.0. Prima di CL2.0, la dimensione del lavoro globale deve essere un multiplo delle dimensioni del lavoro locale, altrimenti verrà visualizzato un messaggio di errore quando si esegue clEnqueueNDRangeKernel.

Ma da CL2.0, questo non è più necessario. È possibile utilizzare qualsiasi dimensione di lavoro globale che si adatti alle dimensioni dell'applicazione. Tuttavia, ricorda che l'implementazione hardware potrebbe ancora utilizzare il "vecchio" modo, che significa riempire la dimensione del gruppo di lavoro globale. Pertanto, rende le prestazioni altamente dipendenti dall'architettura hardware. È possibile che si notino prestazioni piuttosto diverse su hardware/piattaforme differenti. Inoltre, vuoi rendere la tua applicazione compatibile per supportare la piattaforma precedente che supporta solo CL fino alla versione 1.2. Quindi, penso che questa nuova funzionalità aggiunta nel CL2.0 è solo per una facile programmazione, per ottenere migliori prestazioni controllabile e la compatibilità a ritroso, vi suggerisco di utilizzare ancora il seguente metodo citato da voi:

Aumentare le dimensioni del il lavoro globale deve essere il multiplo più vicino delle dimensioni del gruppo di lavoro, mantenendo lo stesso valore di ma controllando i limiti nel kernel per evitare il segfaulting, ovvero non eseguire nulla sugli elementi di lavoro fuori dal limite dell'output desiderato. (Questo sembra il modo migliore.)

Risposta: hai assolutamente ragione. Questo è il modo giusto per gestire questo caso. Progettare con cura le dimensioni del gruppo di lavoro locale (considerando fattori come l'utilizzo del registro, l'hit/miss della cache, il modello di accesso alla memoria e così via). E poi tampona le tue dimensioni di lavoro globali a un multiplo delle dimensioni del lavoro locale. Allora, sei a posto.

Un'altra cosa da considerare è che è possibile utilizzare l'oggetto immagine per memorizzare i dati anziché il buffer, se nel kernel sono presenti molti controlli di limiti. Per l'immagine, il controllo dei confini viene eseguito automaticamente dall'hardware, quasi senza sovraccarico nella maggior parte delle implementazioni. Pertanto, riempendo le dimensioni del lavoro globale, memorizzate i dati nell'oggetto immagine, quindi, è sufficiente scrivere normalmente il codice senza preoccuparsi del controllo dei confini.

Problemi correlati