13.04.2013 Views

Técnicas de Otimização de Código para Placas de ... - UFMG

Técnicas de Otimização de Código para Placas de ... - UFMG

Técnicas de Otimização de Código para Placas de ... - UFMG

SHOW MORE
SHOW LESS

Create successful ePaper yourself

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

__global__ void matSumKernel<br />

( f l o a t∗ S, f l o a t∗ A, f l o a t∗ B, i n t si<strong>de</strong> ) {<br />

i n t i = b l o c k I d x . y∗blockDim . y + threadIdx . y ;<br />

i n t j = b l o c k I d x . x∗blockDim . x + threadIdx . x ;<br />

i n t i j = i∗si<strong>de</strong> + j ;<br />

i f ( i j < si<strong>de</strong>∗si<strong>de</strong> ) {<br />

S [ i j ] = A [ i j ] + B [ i j ] ;<br />

}<br />

}<br />

Figura 1.7. Kernel CUDA equivalente ao programa<br />

C da figura 1.5<br />

milar po<strong>de</strong> ser feito em CUDA.<br />

A figura 1.7 mostra o kernel que é responsável por realizar<br />

a soma matricial. Uma constante em nossos exemplos será a<br />

forma <strong>de</strong> representar matrizes: estas serão sempre linearizadas.<br />

Conforme ficará mais claro adiante, a transmissão <strong>de</strong> dados<br />

entre CPU e GPU é por <strong>de</strong>mais lenta. Por isto, é preferível<br />

enviar estes dados em uma única viagem, em vez <strong>de</strong> termos<br />

<strong>de</strong> transmitir <strong>para</strong> a GPU as muitas colunas que compõem uma<br />

matriz alocada dinamicamente.<br />

O programa da figura 1.5 <strong>de</strong>screve um problema embaraçosamente<br />

<strong>para</strong>lelo, uma vez que não há <strong>de</strong>pendências entre as<br />

iterações do laço. Este tipo <strong>de</strong> aplicação é mais comum que a<br />

princípio po<strong>de</strong>ríamos imaginar; porém, existem também muitas<br />

aplicações em que as <strong>de</strong>pendências temporais estão presentes.<br />

Consi<strong>de</strong>remos, por exemplo, o programa da figura 1.8, cujo<br />

espaço <strong>de</strong> iterações está representado na figura 1.9. As setas<br />

mostram a direção das <strong>de</strong>pendências entre as iterações. Este<br />

programa não é tão <strong>para</strong>lelo quanto aquele na figura 1.5, uma<br />

vez que a iteração (i, j) <strong>de</strong>pen<strong>de</strong> da iteração (i, j−1). No mo<strong>de</strong>lo<br />

PRAM, po<strong>de</strong>ríamos atribuir uma linha <strong>de</strong>ste espaço <strong>para</strong> cada<br />

processador; <strong>de</strong>sta forma, convertendo um algoritmo <strong>de</strong> complexida<strong>de</strong><br />

quadrática <strong>para</strong> um algoritmo equivalente <strong>de</strong> complexida<strong>de</strong><br />

linear. Isto sem que aumentássemos a carga <strong>de</strong> trabalho<br />

total necessária <strong>para</strong> a solução do problema; isto é, cada algoritmo<br />

totaliza uma quantida<strong>de</strong> quadrática <strong>de</strong> somas.<br />

A figura 1.10 nos dá o programa CUDA que correspon<strong>de</strong><br />

12

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

Saved successfully!

Ooh no, something went wrong!