GPGPU Labor 15.
Párhuzamos primitívek Map Reduce Scan Histogram Compact
Map // TODO // // ID := threadIdx.x + blockIdx.x * blockDim.x // IF ID > dataSize THEN return // data[ID] := square(data[ID]) __global__ void mapKernel(int* data, unsigned int dataSize) { // TODO }
Reduce // TODO // // FOR s = dataSize / 2 ; s > 0 ; s >>= 1 DO: // IF (ID < s) // data[ID] = max(data[ID], data[ID + s]) // SYNCHRONIZE THREADS // __global__ void reduceKernel(float* data, int dataSize) { int id = threadIdx.x + blockIdx.x * blockDim.x; // TODO }
Histogram // TODO // // histogram[data[id]] := histogram[data[id]] + 1 // SYNCHRONIZATION! (atomicADD) __global__ void histogramGlobalKernel(int* data, int* histogram, int dataSize) { // TODO }
Histogram (shared) // TODO // // IF LID < histogramSize DO: // lhistogram[LID] := 0 // SYNCHRONIZE THREADS // // Add data to local histogram // // SYNCHRONIZE THREADS // // IF LID < histogramSize DO: // histogram[LID] = lhistogram[LID] __global__ void histogramLocalKernel(int* data, int* histogram, int dataSize, int histogramSize) { extern __shared__ int lhistogram[]; int id = threadIdx.x + blockIdx.x * blockDim.x; int lid = threadIdx.x; // TODO }
Scan (exclusive) // TODO // // IF ID > 0 THEN data[ID] = data[ID - 1] // ELSE data[ID] = 0 // SYNCHRONIZE THREADS // // FOR s = 1; s < dataSize; s *= 2 DO: // tmp := data[ID] // IF ( ID + s < dataSize THEN // data[ID + s] += tmp; // SYNCHRONIZE THREADS // // IF(ID = 0) THEN data[ID] = 0; __global__ void exscanKernel(int* data, int dataSize) { int id = threadIdx.x + blockIdx.x * blockDim.x; // TODO }
Scan (exclusive) Módosítsuk a scan-t, hogy tetszőleges méretű adathalmazon működjön
Profiling Nézzük meg az Nsight Performance Analysis segítségével a histogram kerneleket! Nézzük meg a Visual Profilerrel is! Milyen módon optimalizálható a histogram algoritmus?