Qual è la funzione più banale che potrebbero trarre beneficio dall'essere calcolato su una GPU?

StackOverflow https://stackoverflow.com/questions/2443402

  •  19-09-2019
  •  | 
  •  

Domanda

Sono appena agli inizi di apprendimento OpenCL. Sto cercando di avere un'idea di quello che guadagni di prestazioni aspettarsi quando si spostano funzioni / algoritmi per la GPU.

Il kernel più elementare proposta nella maggior tutorial è un kernel che prende due array di numeri e somma il valore degli indici corrispondenti e li aggiunge un terzo array, in questo modo:

__kernel void 
add(__global float *a,
    __global float *b,
    __global float *answer)
{
    int gid = get_global_id(0);
    answer[gid] = a[gid] + b[gid];
}

__kernel void
sub(__global float* n,
    __global float* answer)
{
    int gid = get_global_id(0);
    answer[gid] = n[gid] - 2;
}

__kernel void
ranksort(__global const float *a,
         __global float *answer)
{
  int gid = get_global_id(0);
  int gSize = get_global_size(0);
  int x = 0;
  for(int i = 0; i < gSize; i++){
    if(a[gid] > a[i]) x++;
  }
  answer[x] = a[gid];
}

Io parto dal presupposto che si potrebbe mai giustificare il calcolo di questo sulla GPU, il trasferimento di memoria sarebbe fuori di peso il tempo necessario calcolare questo sulla CPU da grandezze (potrei sbagliarmi su questo, quindi questa domanda).

Quello che mi chiedo è quello che sarebbe l'esempio più banale in cui ci si aspetta significativo aumento di velocità quando si usa un kernel OpenCL al posto della CPU?

È stato utile?

Soluzione

se si dispone di una sufficientemente grande insieme di matrici si intende eseguire operazioni di algebra lineare, oppure che si sta essenzialmente eseguendo la stessa operazione su ogni elemento, avrei considerarlo un esempio banale. moltiplicazione di matrici, inoltre, FFT, convoluzione, ecc vedrete un po 'di un aumento di velocità senza fare molto lavoro. Ora, se volete vedere i incrementi nella velocità 100x allora avete bisogno di approfondire la gestione della memoria e conoscere un bel po 'di quello che succede dietro le quinte.

per iniziare, mi sento di raccomandare a cominciare pycuda dato che è abbastanza semplice per iniziare in quanto fornisce un alto livello di astrazione e vi permetterà di saltare molto rapidamente. controllare questo corso di elaborazione in parallelo CUDA utilizzando dalla University of Illinois http: //courses.ece. illinois.edu/ece498/al/ quando si è pronti a tuffarsi in più.

Altri suggerimenti

dipende dalla definizione di banale. a mio parere sarebbe prodotto Matrix, dal momento che ha O(3)/O(2) calcolare al rapporto di memoria. Gli algoritmi che presentano rapporti simili, sono suscettibili di beneficiare di essere gareggiato sulla GPU.

Mentre il kernel è chiaramente molto banale può essere un utile esempio, è completamente la memoria vincolata dal momento che per ogni elemento si hanno due letture e una scrittura, e una sola operazione aritmetica. Ci sono alcune istruzioni per calcolare l'indirizzo ecc, ma tutto questo ammonta a praticamente nulla rispetto al costo di accedere alla memoria.

Supponendo che i dati sono già sulla GPU, è possibile beneficiare di molto elevata larghezza di banda della GPU alla memoria anche per questo semplice kernel.

Naturalmente, le GPU si basano su di voi avere abbastanza thread per nascondere la latenza di memoria, quindi la dimensione del gruppo di lavoro locale dovrebbe essere abbastanza grande (diciamo 256 o 512) e la dimensione del gruppo di lavoro globale dovrebbe essere molto grande (ad esempio, centinaia di migliaia ) per questo per essere efficace, ma questo è il tipo di punto!

So che la questione è piuttosto vecchio, ma ... ho scoperto che i calcoli del l'insieme di Mandelbrot è proprio ottimale per la GPU. Hai un vettore complesso di ingresso (float2) e di un'uscita scalare (int) e avrete un centinaio di operazioni al vettore di input in media.

Potrebbe essere usato come un buon esempio di applicazione, in quanto ...

  • ha un set di dati di ingresso 2-dimensionale (calcola un'immagine)
  • si può spiegare il motivo per cui fronti d'onda e 2 di trasformazione dimensionale è utile in alcuni casi
  • dimostra tipi di dati vettore
  • produce un quadro, che è rapidamente verificabile da occhi umani (debug)
  • può essere facilmente estesa da: mappatura colore (__constant), trasformazione float4 anziché float2 (ottimizzazione), producendo int4 vettori di uscita (R, G, B, A) (ottimizzazione). Livelli di riduzione (RGBA) => (RGB)
  • la conoscenza matematica necessaria è accettabile (formula semplice)

Saluti, Stefan

Dopo la moltiplicazione matriciale direi immagine convoluzione (come sfocatura, denoising ecc). Scopri di AMD esercitazione .

Ciò che è "più banale" è una questione di opinione, ma direi che il calcolo un'immagine dell'insieme di Mandelbrot è un'applicazione piuttosto semplice utilizzando la GPU. Ogni punto è del tutto indipendente da ogni altro punto, in modo da poter avviare un thread per ogni punto e ottenere un enorme aumento di velocità. La formula stessa che viene iterata è una semplice funzione quadratica. L'ho usato come esempio in un tutorial che può essere trovato sul mio blog qui , solo calcolando i numeri senza nemmeno fare un'immagine per rendere ancora più semplice. Quasi ogni imbarazzante parallelo (vedi voce su Wikipedia) problema è una buona per cominciare.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top