GPU Programming with CUDA and the PGI Accelerator Programming

GPU Programming with CUDA and the PGI Accelerator Programming

PGI GPU Programming Tutorial Mar 2011 GPU Programming with Agenda CUDA (C and PGI CUDA Fortran) Introduction and the PGI Accelerator . GPU architecture vs. Host architecture . GPU parallel programming vs. Host parallel programming Programming Model CUDA . CUDA Programming model Michael Wolfe . The Host Program [email protected] . Writing Kernels http://www.pgroup.com . Building and Running CUDA Programs . Performance Tuning March 2011 Accelerator Model . PGI Accelerator Programming Model . Building PGI Accelerator Programs Part 1: Introduction . Directive Details . Interpreting Compiler Feedback . Tips and Tricks 1-1 . Performance Tuning 1-2 Host Architecture Features Example Systems Register files (integer, float) Scalar pipeline Functional units (integer, float, address), Icache, Dcache . MIPS, SPARC LIW Execution pipeline (fetch,decode,issue,execute,cache,commit) . Multiflow Trace, Cydrome Cydra-5, i860 . branch prediction, hazards (control, data, structural) . pipelined functional units, superpipelining, register bypass Multithreaded . stall, scoreboarding, reservation stations, register renaming . Denelcor HEP, Tera, GPUs, Sparc Niagara Multiscalar execution (superscalar, control unit lookahead) . SMT: Intel hyperthreading . LIW (long instruction word) Vector Multithreading, Simultaneous multithreading . Cray, Convex, NEC Multiprocessors Vector instruction set . Sequent, Encore, SGI, many Multiprocessor, Multicore, coherent caches (MESI protocols) 1-3 1-4 © Copyright 2009-2011, The Portland Group, Inc. PGI GPU Programming Tutorial Mar 2011 Making It Faster AMD “Magny-Cours” Processor: . Faster clocks . More work per clock: . superscalar . VLIW . more cores . vector / SIMD instructions Memory . Latency reduction . Latency tolerance 1-5 Abstracted x64+Tesla Architecture Abstracted x64+Fermi Architecture 1-7 1-8 © Copyright 2009-2011, The Portland Group, Inc. PGI GPU Programming Tutorial Mar 2011 GPU Architecture Features Tesla-10 Features Summary Optimized for high degree of regular parallelism Massively parallel thread processors Classically optimized for low precision . Organized into multiprocessors . up to 30, see deviceQuery or pgaccelinfo . Fermi supports double precision at ½ single precision bandwidth . Physically: 8 thread processors per multiprocessor High bandwidth memory (Fermi supports ECC) . Logically: 32 threads per warp Highly multithreaded (slack parallelism) Memory hierarchy Hardware thread scheduling . host memory, device memory, constant memory, shared memory, register Non-coherent software-managed data caches Queue of operations (kernels) on device . Fermi has two-level hardware data cache No multiprocessor memory model guarantees . some guarantees with fence operations 1-9 1-10 Fermi (Tesla-20) Features Summary Identifying your GPU Massively parallel thread processors pgaccelinfo . Organized into multiprocessors deviceQuery (CUDA SDK) . up to 16, see deviceQuery or pgaccelinfo Linux . Physically: two groups of 16 thread processors per multiprocessor . Logically: still 32 threads per warp . NVIDIA driver powers down inactive devices Memory hierarchy Windows . host memory, device memory (two level hardware cache), constant . You must be at the console to access the GPU memory, (configurable) shared memory, register Mac OSX Queue of operations (kernels) on device . Your notebook may have two GPUs, but OS will power one down ECC memory protection (supported, not default) Much improved double precision performance Hardware 32-bit integer multiply 1-11 1-12 © Copyright 2009-2011, The Portland Group, Inc. PGI GPU Programming Tutorial Mar 2011 Parallel Programming on CPUs pthreads main routine call pthread_create( t1, NULL, jacobi, 1 ) Instruction level parallelism (ILP) call pthread_create( t2, NULL, jacobi, 2 ) . Loop unrolling, instruction scheduling call pthread_create( t3, NULL, jacobi, 3 ) Vector parallelism call jacobi( 4 ) call pthread_join( t1, NULL ) . Vectorized loops (or vector intrinsics) call pthread_join( t2, NULL ) Thread level / Multiprocessor / multicore parallelism call pthread_join( t3, NULL ) . Parallel loops, parallel tasks . Posix threads, OpenMP, Cilk, TBB, ..... Large scale cluster / multicomputer parallelism . MPI (& HPF, co-array Fortran, UPC, Titanium, X10, Fortress, Chapel) 1-13 1-14 Jacobi Relaxation with pthreads subroutine OpenMP directives subroutine jacobi( threadnum ) lchange = 0 change = 0 do j = threadnum+1, n-1, numthreads !$omp parallel private(i,j) do i = 2, m-1 !$omp do reduction(max:change) newa(i,j) = w0*a(i,j) + & do j = 2, n-1 w1 * (a(i-1,j) + a(i,j-1) + & do i = 2, m-1 a(i+1,j) + a(i,j+1)) + & newa(i,j) = w0*a(i,j) + & w2 * (a(i-1,j-1) + a(i-1,j+1) + & w1 * (a(i-1,j) + a(i,j-1) + & a(i+1,j-1) + a(i+1,j+1)) a(i+1,j) + a(i,j+1)) + & lchange = max(lchange,abs(newa(i,j)-a(i,j))) w2 * (a(i-1,j-1) + a(i-1,j+1) + & enddo a(i+1,j-1) + a(i+1,j+1)) enddo change = max(change,abs(newa(i,j)-a(i,j))) call pthread_mutex_lock( lck ) enddo change = max(change,lchange) enddo call pthread_mutex_unlock( lck ) !$omp end parallel end subroutine 1-15 1-16 © Copyright 2009-2011, The Portland Group, Inc. PGI GPU Programming Tutorial Mar 2011 Behind the Scenes More Behind the Scenes Compiler generates code for N threads: Virtualization penalties . split up the iterations across N threads . load balancing . accumulate N partial sums (no synchronization) . cache locality . accumulate final sum as threads complete . vectorization within the threads . thread management Assumptions . loop scheduling (which thread does what iteration) . uniform memory access costs . NUMA memory access penalty . coherent cache mechanism 1-17 1-18 Parallel Programming on GPUs GPU Programming High degree of regular parallelism Allocate data on the GPU . lots of scalar threads Move data from host, or initialize data on GPU . threads organized into thread groups / blocks Launch kernel(s) . SIMD, pseudo-SIMD . thread groups organized into grid . GPU driver can generate ISA code at runtime . MIMD . preserves forward compatibility without requiring ISA compatibility Languages Gather results from GPU . CUDA, OpenCL, (Brook, Brook+), graphics: OpenGL, DirectX . may include vector datatypes (float4, int2) Deallocate data Platforms . (Rapidmind, now owned by Intel) 1-19 1-20 © Copyright 2009-2011, The Portland Group, Inc. PGI GPU Programming Tutorial Mar 2011 Appropriate GPU programs Jacobi Relaxation Characterized by nested parallel loops change = 0; for( i = 1; i < m-1; ++i ){ High compute intensity for( j = 1; j < n-1; ++j ){ Regular data access newa[j][i] = w0*a[j][i] + w1 * (a[j][i-1] + a[j-1][i] + Isolated host/GPU data movement a[j][i+1] + a[j+1][i]) + w2 * (a[j-1][i-1] + a[j+1][i-1] + a[j-1][i+1] + a[j+1][i+1]); change = fmaxf(change,fabsf(newa[j][i]-a[j][i])); } } 1-21 1-22 Host-side CUDA C GPU Control Code Device-side CUDA C (1) __device__ float change; extern "C" __global__ void jacobikernel( float* a, float* anew, float* lchange, int n, int m ) memsize = sizeof(float)*n*m { cudaMalloc( &da, memsize ); int ti = threadIdx.x, tj = threadIdx.y; /* local indices */ cudaMalloc( &dnewa, memsize ); int i = blockIdx.x*16+ti+1, j = blockIdx.y*16+tj+1; /* global */ cudaMalloc( &lchange, (n/16)*(m/16) ); __shared__ float mychange[16*16]; float mya, oldmya = a[j*m+i]; cudaMemcpy( da, a, memsize, cudaMemcpyHostToDevice ); mya = w0 * oldmya + dim3 threads( 16, 16 ); w1 * (a[j*m+i-1] + a[(j-1)*m+i] + dim3 blocks( n/16, m/16 ); a[j*m+i+1] + a[(j+1)*m+i] + jacobikernel<<<blocks,threads>>>( da, dnewa, lchange, n, m ); w2 * (a[(j-1)*m+i-1] + a[(j+1)*m+i-1] + reductionkernel<<<1,256>>>( lchange, (n/16)*(m/16) ); a[(j-1)*m+i+1] + a[(j+1)*m+i+1]); anew[j*m+i] = mya; cudaMemcpy( a, dnewa, memsize, cudaMemcpyDeviceToHost ); /* this thread's "change" */ mychange[ti+16*tj] = fabs(mya-oldmya); cudaFree( da ); __syncthreads(); cudaFree( dnewa ); cudaFree( lchange ); 1-23 1-24 © Copyright 2009-2011, The Portland Group, Inc. PGI GPU Programming Tutorial Mar 2011 Device-side CUDA C (2) Device-side CUDA C (3) /* reduce all "change" values for this thread block /* reduce all thread block's "change" values to a single value */ * to a single value */ extern “C” __global void n = 256; reductionkernel( float* lchange, int n ) while( (n >>= 1) > 0 ){ { if( tx+ty*16 < n ) __shared__ float mychange[256]; mychange[ti+tj*16] = fmaxf( mychange[ti+tj*16], float mych; mychange[ti+tj*16+n]); int i = threadIdx.x, m; __syncthreads(); mych = lchange[i]; } m = 256; /* store this thread block's "change" */ while( m <= n ){ if(tx==0&&ty==0) mych = fmaxf(mych,lchange[m]); lchange[blockIdx.x+gridDim.x*blockIdx.y] = mychange[0]; m += 256; } } mychange[i] = mych; __syncthreads(); 1-25 1-26 Device-side CUDA C (4) Behind the Scenes n = 256; What you write is what you get while( (n >>= 1) > 0 ){ if(i<n) mychange[i] = fmaxf(mychange[i],mychange[i+n]); Implicitly parallel __syncthreads(); } . threads into warps if(i==0) lchange[0] = mychange[0]; . warps into thread groups } . thread groups into a grid Hardware thread scheduler Highly multithreaded 1-27 1-28 © Copyright 2009-2011, The Portland Group, Inc. PGI GPU Programming Tutorial Mar 2011 Better Device-side CUDA C (1) extern "C" __global__ void jacobikernel( float* a, float* anew, float* lchange, int n, int m ) { int ti = threadIdx.x, tj = threadIdx.y; /* local indices */ int i = blockIdx.x*16+ti, j = blockIdx.y*16+tj; /* global */ __shared__ float mychange[16*16], b[18][18]; float mya, oldmya; b[tj][ti] = a[(j-1)*m+i-1]; if(ti<2) b[tj][ti+16] = a[(j-1)*m+i+15]; Time for a Live Demo if(tj<2) b[tj+16][ti] = a[(j+15)*m+i-1]; if(ti<2&&tj<2) b[tj+16][ti+16] = a[(j+15)*m+i+15]; oldmya = b[tj+1][ti+1]; __syncthreads(); mya = w0 * oldmya + w1 * (b[tj+1][ti] + b[tj][ti+1] + b[tj+1][ti+2] + b[tj+2][ti+1]) + w2 * (b[tj][ti] + b[tj+2][ti] + b[tj][ti+2] + b[tj+2][ti+2]); newa[j][i] = mya; /* this thread's "change" */ mychange[ti+16*tj] = fabs(mya-oldmya); 1-29 1-30 __syncthreads(); Copyright Notice © Contents copyright 2009-2011, The Portland Group, Inc.

View Full Text

Details

  • File Type
    pdf
  • Upload Time
    -
  • Content Languages
    English
  • Upload User
    Anonymous/Not logged-in
  • File Pages
    8 Page
  • File Size
    -

Download

Channel Download Status
Express Download Enable

Copyright

We respect the copyrights and intellectual property rights of all users. All uploaded documents are either original works of the uploader or authorized works of the rightful owners.

  • Not to be reproduced or distributed without explicit permission.
  • Not used for commercial purposes outside of approved use cases.
  • Not used to infringe on the rights of the original creators.
  • If you believe any content infringes your copyright, please contact us immediately.

Support

For help with questions, suggestions, or problems, please contact us