13.07.2015 Views

Tiled Matrix Multiplication lecture 21 jan 2013.pdf

Tiled Matrix Multiplication lecture 21 jan 2013.pdf

Tiled Matrix Multiplication lecture 21 jan 2013.pdf

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

TILE_WIDTHETILE_WIDTHTILE_WIDTH<strong>Tiled</strong> Multiply• Break up the execution of thekernel into phases so that thedata accesses in each phase isfocused on one subset (tile) ofMd and NdNdbx0 1 2tx012TILE_WIDTH-1WIDTH WIDTHMdPd0by1ty012Pd subTILE_WIDTH-1TILE_WIDTHTILE_WIDTHTILE_WIDTH2WIDTHWIDTH1


A Small ExampleNd 1,0 Nd 0,0Nd 0,1 Nd 1,1Nd 1,2Nd 0,3 Nd 1,3Nd 0,2Md 0,0 Md 1,0 Md 2,0 Md 3,0 Pd 0,0 Pd 1,0 Pd 2,0 Pd 3,0Md 0,1 Md 1,1 Md 2,1 Md 3,1 Pd 0,1 Pd 1,1 Pd 2,1 Pd 3,1Pd 0,2 Pd 1,2 Pd 2,2 Pd 3,2Pd 0,3 Pd 1,3 Pd 2,3 Pd 3,32


Every Md and Nd Element is usedexactly twice in generating a 2X2 tile of PP 0,0thread 0,0P 1,0thread 1,0P 0,1thread 0,1P 1,1thread 1,1M 0,0 * N 0,0 M 0,0 * N 1,0 M 0,1 * N 0,0 M 0,1 * N 1,0AccessorderM 1,0 * N 0,1 M 1,0 * N 1,1 M 1,1 * N 0,1 M 1,1 * N 1,1M 2,0 * N 0,2 M 2,0 * N 1,2 M 2,1 * N 0,2 M 2,1 * N 1,2M 3,0 * N 0,3 M 3,0 * N 1,3 M 3,1 * N 0,3 M 3,1 * N 1,33


Breaking Md and Nd into Tiles• Break up the innerproduct loop of eachthread into phases• At the beginning of eachphase, load the Md andNd elements thateveryone needs duringthe phase into sharedmemory• Everyone access the Mdand Nd elements from theshared memory duringthe phaseNd 1,0 Nd 0,0Nd 0,1 Nd 1,1Nd 0,2 Nd 1,2Nd 0,3 Nd 1,3Md 0,0 Md 1,0 Md 2,0 Md 3,0 Pd 0,0 Pd 1,0 Pd 2,0 Pd 3,0Md 0,1 Md 1,1 Md 2,1 Md 3,1 Pd 0,1 Pd 1,1 Pd 2,1 Pd 3,1Pd 0,2 Pd 1,2 Pd 2,2 Pd 3,2Pd 0,3 Pd 1,3 Pd 2,3 Pd 3,34


Each phase of a Thread Block uses onetile from Md and one from NdPhase 1 Phase 2Step 4 Step 5 Step 6T 0,0 Md 0,0↓Mds 0,0Nd 0,0 PValue 0,0 +=↓ Mds 0,0 *Nds 0,0 +NdsMds 1,0 *Nds 0,10,0Md 2,0↓Mds 0,0Nd 0,2 PValue 0,0 +=↓ Mds 0,0 *Nds 0,0 +NdsMds 1,0 *Nds 0,10,0T 1,0 Md 1,0↓Mds 1,0Nd 1,0 PValue 1,0 += Md 3,0↓ Mds 0,0 *Nds 1,0 + ↓NdsMds 1,0 *Nds 1,1 1,0Mds 1,0Nd 1,2↓Nds 1,0PValue 1,0 +=Mds 0,0 *Nds 1,0 +Mds 1,0 *Nds 1,1T 0,1 Md 0,1 Nd 0,1 PdValue 0,1 += Md 2,1 Nd 0,3↓ ↓ Mds 0,1 *Nds 0,0 + ↓ ↓Mds 0,1 NdsMds 1,1 *Nds 0,1 0,1 Mds 0 , 1T 1,1 Md 1,1 Nd 1,1 PdValue 1,1 += Md 3,1↓ ↓ Mds 0,1 *Nds 1,0 + ↓Mds 1,1 NdsMds 1,1 *Nds 1,1 1,1Mds 1,1Nds 0,1Nd 1,3↓Nds 1,1PdValue 0,1 +=Mds 0,1 *Nds 0,0 +Mds 1,1 *Nds 0,1PdValue 1,1 +=Mds 0,1 *Nds 1,0 +Mds 1,1 *Nds 1,1time5


<strong>Tiled</strong> <strong>Matrix</strong> <strong>Multiplication</strong> Kernel__global__ void <strong>Matrix</strong>MulKernel(float* Md, float* Nd, float* Pd, int Width){1. __shared__float Mds[TILE_WIDTH][TILE_WIDTH];2. __shared__float Nds[TILE_WIDTH][TILE_WIDTH];3. int bx = blockIdx.x; int by = blockIdx.y;4. int tx = threadIdx.x; int ty = threadIdx.y;// Identify the row and column of the Pd element to work on5. int Row = by * TILE_WIDTH + ty;6. int Col = bx * TILE_WIDTH + tx;7. float Pvalue = 0;// Loop over the Md and Nd tiles required to compute the Pd element8. for (int m = 0; m < Width/TILE_WIDTH; ++m) {// Coolaborative loading of Md and Nd tiles into shared memory9. Mds[ty][tx] = Md[Row*Width + (m*TILE_WIDTH + tx)];10. Nds[ty][tx] = Nd[Col + (m*TILE_WIDTH + ty)*Width];}11. __syncthreads();12. for (int k = 0; k < TILE_WIDTH; ++k)12. Pvalue += Mds[ty][k] * Nds[k][tx];13. __synchthreads();14. }16. Pd[Row*Width+Col] = Pvalue;}6


CUDA Code – Kernel ExecutionConfiguration// Setup the execution configurationdim3 dimBlock(TILE_WIDTH, TILE_WIDTH);dim3 dimGrid(Width / TILE_WIDTH,Width / TILE_WIDTH);7


First-order Size Considerations in G80• Each thread block should have many threads– TILE_WIDTH of 16 gives 16*16 = 256 threads• There should be many thread blocks– A 1024*1024 Pd gives 64*64 = 4096 Thread Blocks– TILE_WIDTH of 16 gives each SM 3 blocks, 768 threads (fullcapacity)• Each thread block perform 2*256 = 512 float loads fromglobal memory for 256 * (2*16) = 8,192 mul/addoperations.– Memory bandwidth no longer a limiting factor8


TILE_WIDTHETILE_WIDTHTILE_WIDTH<strong>Tiled</strong> Multiplybx0 1 2• Each block computes onesquare sub-matrix Pd sub of sizeTILE_WIDTH• Each thread computes oneelement of Pd subNdmbxtx012TILE_WIDTH-1kWIDTH WIDTH0MdmbyPdby1ty012kPd subTILE_WIDTH-1TILE_WIDTHTILE_WIDTHTILE_WIDTH2WIDTHWIDTH9


G80 Shared Memory and Threading• Each SM in G80 has 16KB shared memory– SM size is implementation dependent!– For TILE_WIDTH = 16, each thread block uses 2*256*4B = 2KB ofshared memory.– The shared memory can potentially have up to 8 Thread Blocks activelyexecuting• This allows up to 8*512 = 4,096 pending loads. (2 per thread, 256 threads perblock)• The threading model limits the number of thread blocks to 3 so sharedmemory is not the limiting factor here– The next TILE_WIDTH 32 would lead to 2*32*32*4B= 8KB sharedmemory usage per thread block, allowing only up to two thread blocksactive at the same time• Using 16x16 tiling, we reduce the accesses to the global memory bya factor of 16– The 86.4B/s bandwidth can now support (86.4/4)*16 = 347.6 GFLOPS!10


Tiling Size Effectstile do n lytile d &u n ro lle dtile do n lytile d &u n ro lle dtile do n lytile d &u n ro lle dtile do n lytile d &u n ro lle d100908070GFLOPS6050403020100no t tile d 4 x4 tile s 8 x8 tile s 1 2 x1 2 tile s 1 6 x1 6 tile s11


Summary- Typical Structure of aCUDA Program• Global variables declaration– __host__– __device__... __global__, __constant__, __texture__• Function prototypes– __global__ void kernelOne(…)– float handyFunction(…)• Main ()– allocate memory space on the device – cudaMalloc(&d_GlblVarPtr, bytes )– transfer data from host to device – cudaMemCpy(d_GlblVarPtr, h_Gl…)– execution configuration setup– kernel call – kernelOne( args… );– transfer results from device to host – cudaMemCpy(h_GlblVarPtr,…)– optional: compare against golden (host computed) solution• Kernel – void kernelOne(type args,…)– variables declaration - __local__, __shared__• automatic variables transparently assigned to registers or local memory– syncthreads()…• Other functions– float handyFunction(int inVar…);repeatasneeded12

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!