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.

1.3. Análises e Otimizações <strong>de</strong> Divergência<br />

Muitas das otimizações que vimos na Seção 1.2, tais como<br />

ladrilhamento e alocação <strong>de</strong> registradores, são técnicas clássicas<br />

<strong>de</strong> compilação [1], po<strong>de</strong>ndo ser usadas tanto em programas<br />

sequenciais quanto em programas <strong>para</strong>lelos. Existem, contudo,<br />

otimizações <strong>de</strong> código que fazem sentido apenas quando usadas<br />

sobre máquinas SIMD, como os processadores <strong>de</strong> warps<br />

em CUDA. Esta peculiarida<strong>de</strong> <strong>de</strong>ve-se a um fenômeno <strong>de</strong>nominado<br />

execução divergente, o qual <strong>de</strong>screveremos nesta seção.<br />

Warps <strong>de</strong> threads. Em uma GPU, threads são organizadas<br />

em grupos que executam em passo único, chamados warps no<br />

jargão da NVIDIA e frentes <strong>de</strong> onda no jargão da ATI. Para enten<strong>de</strong>r<br />

as regras que governam o funcionamento das threads<br />

em um mesmo warp, imaginemos que cada warp po<strong>de</strong> usar várias<br />

unida<strong>de</strong>s lógicas e aritméticas; porém, existe somente um<br />

buscador <strong>de</strong> instruções por warp. Por exemplo, a placa Ge-<br />

Force 8800 é capaz <strong>de</strong> executar 16 warps simultaneamente.<br />

Cada warp agrupa 32 threads e po<strong>de</strong> usar 8 unida<strong>de</strong>s lógicas e<br />

aritméticas. Como existe somente um buscador <strong>de</strong> instruções,<br />

cada warp po<strong>de</strong> executar 32 instâncias da mesma instrução em<br />

quatro ciclos <strong>de</strong> pipeline da GPU. Cada uma <strong>de</strong>stas instruções,<br />

embora <strong>de</strong>signando a mesma operação, não precisa usar os<br />

mesmos dados. Trazendo <strong>de</strong> volta nossa analogia do pelotão<br />

<strong>de</strong> fuzilamento, cada soldado seria uma unida<strong>de</strong> <strong>de</strong> processamento,<br />

o capitão que lhes grita as or<strong>de</strong>ns faz o papel do buscador<br />

<strong>de</strong> instruções e cada fuzil representa os dados sendo processados.<br />

Evi<strong>de</strong>ntemente este mo<strong>de</strong>lo <strong>de</strong> execução é mais eficiente<br />

quando usado sobre aplicações regulares em que todas<br />

as threads po<strong>de</strong>m executar as mesmas tarefas. Infelizmente<br />

muitas das aplicações que gostaríamos <strong>de</strong> <strong>para</strong>lelizar não são<br />

tão regulares e divergências po<strong>de</strong>m acontecer entre as threads.<br />

Dizemos que um programa é divergente se durante sua execução<br />

threads agrupadas no mesmo warp seguem caminhos<br />

diferentes logo após terem processado um <strong>de</strong>svio condicional.<br />

Divergências ocorrem, então, <strong>de</strong>vido à <strong>de</strong>svios condicionais.<br />

A condição <strong>de</strong> <strong>de</strong>svio po<strong>de</strong> ser verda<strong>de</strong>ira <strong>para</strong> algumas threads<br />

e falsa <strong>para</strong> outras. Dado que cada warp possui acesso<br />

no máximo a uma instrução a cada ciclo <strong>de</strong> execução, em vista<br />

34

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

Saved successfully!

Ooh no, something went wrong!