Domanda

In un kernel CUDA, Ho codice simile alla seguente. Sto cercando di calcolare un numeratore per thread, e si accumulano i numeratori sopra il blocco per calcolare un denominatore, e poi tornare il rapporto. Tuttavia, CUDA sta impostando il valore di denom a qualsiasi valore viene calcolato per numer dal filo nel blocco con il maggior threadIdx.x, piuttosto che la somma del valore numer calcolata su tutti i fili nel blocco. Qualcuno sa che cosa sta succedendo?

extern __shared__ float s_shared[];

float numer = //calculate numerator

s_shared[threadIdx.x] = numer;
s_shared[blockDim.x] += numer;
__syncthreads();

float denom = s_shared[blockDim.x];
float result = numer/denom;

"risultato" deve sempre essere compreso tra 0 e 1 e deve sommare a 1 attraverso il blocco, ma invece è uguale a 1.0 per ogni filo dove threadIdx.x è il massimo, e altri valori non limitato alla gamma di gli altri thread nel blocco.

È stato utile?

Soluzione

Non stai sincronizzando la somma correttamente al blockDim.x posizione. Nessuno dei fili sono in attesa di vedere ciò che altri hanno scritto prima di aggiungere la loro somma. Un po 'come

  • Tutti segna zero,
  • va a casa, calcola lo zero + numer.
  • Everone scrive lo zero + numer alla locazione di memoria

L'alta ThreadID vince b / c ha una elevata probabilità di agire scorso, suppongo.

Che cosa si vuole fare, invece, al fine di fare una somma rapida, è quello di fare una somma binario su s_shared[threadIdx.x]

  • ognuno scrive il numer
  • metà dei fili calcola somme di coppia e scrivono quelli in una nuova posizione
  • un quarto dei fili caluclate somme di coppie di coppie, e scrivere quelle in una nuova posizione
  • etc
  • fino a quando v'è solo un filo e una somma

Questo richiede O (n) di lavoro e O (log n).

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