ECE 408 Fall 2015 Applied Parallel Programming Lecture

  • Slides: 11
Download presentation
ECE 408 Fall 2015 Applied Parallel Programming Lecture 19: Atomic Operations and Histogramming ©

ECE 408 Fall 2015 Applied Parallel Programming Lecture 19: Atomic Operations and Histogramming © David Kirk/NVIDIA and Wen-mei W. Hwu ECE 408/CS 483/ECE 498 al, University of Illinois, 20072012 1

CUDA Atomic Operations • • • __syncthreads(); int atomic. Add(int *address, int val); int

CUDA Atomic Operations • • • __syncthreads(); int atomic. Add(int *address, int val); int atomic. Sub(int *address, int val); int atomic. Exch(int *address, int val); int atomic. Min(int *address, int val); int atomic. Max(int *address, int val); unsigned int atomic. Inc(int *address, int val); unsigned int atomic. Dec(int *address, int val); int atomic. CAS(int *address, int compare, int val); • Also atomic. And(), atomic. Or(), atomic. Xor()… • int *address can be in shared memory or global memory © David Kirk/NVIDIA and Wen-mei W. Hwu ECE 408/CS 483/ECE 498 al, University of Illinois, 2007 -2012 2

A Histogram Kernel • The kernel receives a pointer to the input buffer •

A Histogram Kernel • The kernel receives a pointer to the input buffer • Each thread process the input in a strided pattern __global__ void hist(unsigned char *buffer, int size, unsigned int *histo) { int i = thread. Idx. x + block. Idx. x * block. Dim. x; // stride is total number of threads int stride = block. Dim. x * grid. Dim. x; // All threads handle block. Dim. x * grid. Dim. x // consecutive elements while (i < size) { atomic. Add( &(histo[buffer[i]]), 1); i += stride; } } © David Kirk/NVIDIA and Wen-mei W. Hwu ECE 408/CS 483/ECE 498 al, University of Illinois, 20072012 3

Atomic Operations on DRAM © David Kirk/NVIDIA and Wen-mei W. Hwu ECE 408/CS 483/ECE

Atomic Operations on DRAM © David Kirk/NVIDIA and Wen-mei W. Hwu ECE 408/CS 483/ECE 498 al, University of Illinois, 20072012 • An atomic operation starts with a read, with a latency of a few hundred cycles • The atomic operation ends with a write, with a latency of a few hundred cycles • During this whole time, no one else can access the location 4

Atomic Operations on DRAM • Each Load-Modify-Store has two full memory access delays –

Atomic Operations on DRAM • Each Load-Modify-Store has two full memory access delays – All atomic operations on the same variable (RAM location) are serialized time Operation DRAM delay transfer delay atomic operation N © David Kirk/NVIDIA and Wen-mei W. Hwu ECE 408/CS 483/ECE 498 al, University of Illinois, 20072012 5

Latency determines throughput of atomic operations • Throughput of an atomic operation is the

Latency determines throughput of atomic operations • Throughput of an atomic operation is the rate at which the application can execute an atomic operation on a particular location. • The rate is limited by the total latency of the readmodify-write sequence, typically more than 1000 cycles for global memory (DRAM) locations. • This means that if many threads attempt to do atomic operation on the same location (contention), the memory bandwidth is reduced to < 1/1000! © David Kirk/NVIDIA and Wen-mei W. Hwu ECE 408/CS 483/ECE 498 al, University of Illinois, 20072012 6

Hardware Improvements (cont. ) • Atomic operations on Fermi L 2 cache – medium

Hardware Improvements (cont. ) • Atomic operations on Fermi L 2 cache – medium latency, but still serialized – Global to all blocks – “Free improvement” on Global Memory atomics time. . data transfer atomic operation N © David Kirk/NVIDIA and Wen-mei W. Hwu ECE 408/CS 483/ECE 498 al, University of Illinois, 20072012 data transfer atomic operation N+1 7

Hardware Improvements • Atomic operations on Shared Memory – Very short latency, but still

Hardware Improvements • Atomic operations on Shared Memory – Very short latency, but still serialized – Private to each thread block – Need algorithm work by programmers (more later) time. . data transfer atomic operation N+1 © David Kirk/NVIDIA and Wen-mei W. Hwu ECE 408/CS 483/ECE 498 al, University of Illinois, 20072012 8

Atomics in Shared Memory Requires Privatization __global__ void hist(unsigned char *buffer, int size, unsigned

Atomics in Shared Memory Requires Privatization __global__ void hist(unsigned char *buffer, int size, unsigned int *histo) { __shared__ unsigned int histo_private[256]; if (thread. Idx. x < 256) histo_private[threadidx. x] = 0; __syncthreads(); int i = thread. Idx. x + block. Idx. x * block. Dim. x; // stride is total number of threads int stride = block. Dim. x * grid. Dim. x; while (i < size) { atomic. Add( &(private_histo[buffer[i]), 1); i += stride; } // wait for all other threads in the block to finish __syncthreads(); if (thread. Idx. x < 256) atomic. Add( &(histo[thread. Idx. x]), private_histo[thread. Idx. x] ); } © David Kirk/NVIDIA and Wen-mei W. Hwu ECE 408/CS 483/ECE 498 al, University of Illinois, 20072012 9

More on Privatization • Privatization is a powerful and frequently used techniques for parallelizing

More on Privatization • Privatization is a powerful and frequently used techniques for parallelizing applications • The operation needs to be associative and commutative – Histogram add operation is associative and commutative • The histogram size needs to be small – Fits into shared memory • What if the histogram is too large to privatize? © David Kirk/NVIDIA and Wen-mei W. Hwu ECE 408/CS 483/ECE 498 al, University of Illinois, 20072012 10

ANY MORE QUESTIONS? © David Kirk/NVIDIA and Wen-mei W. Hwu ECE 408/CS 483/ECE 498

ANY MORE QUESTIONS? © David Kirk/NVIDIA and Wen-mei W. Hwu ECE 408/CS 483/ECE 498 al, University of Illinois, 20072012 11