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
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