1. jul-2011 1
Automatic Thread Extraction with Decoupled Software Pipelining
Guilherme Ottoni Ram Rangan Adam Stoler David I. August
Departments of Computer Science and Electrical Engineering
Princeton University
{ottoni, ram, astoler, august} @ princeton.edu
Resumo realizado por Marcio Machado Pereira – RA 780681
transformações requerem que loops sejam contaveis,
operações exclusivamente em arrays, padrões de acesso de
I. INTRODUÇÃO memória regular, controles de fluxo simples (ou mesmo sem
N o artigo [1], os autores propuseram uma abordagem não-
especulativa para extração automática de threads
chamada Decoupled Software Pipelining (DSWP). DSWP
controle de fluxo), enquanto que DSWP não tem qualquer
dessas restrições.
explora o paralelismo de granularidade mais fina requerendo O mecanismo utilizado para implementar a comunicação
para isto conhecimento da microarquitetura para inter-core foi a matriz de sincronização (synchronization
comunicação inter-core. array). Este mecanismo utiliza duas instruções especiais,
produce e consume que, respectivamente, enviam e recebem
Para um melhor entendimento do leitor, os autores examinam um valor escalar por uma fila FIFO, não bloqueante (a não
o paralelismo obtido pela técnica DOACROSS que é ser nos casos de fila cheia ou vazia) do hardware.
caracterizada pela execução concorrente de partes da iteração
de um loop através de múltiplos cores. As dependências são Os autores investigaram algumas alternativas para o
respeitadas a partir do encaminhamento dos valores de mecanismo synchronization array com o objetivo de reduzir
dependência entre as threads por algum mecanismo de os custos de hardware [2]. Observaram, por exemplo, que as
comunicação (normalmente, memória compartilhada) com filas de comunicação podem ser implementadas através de
sincronização. Como consequencia, o roteamento presente memória compartilhada, por uma pequena penalidade no
entre os cores, estende o caminho crítico do loop por pelo desempenho. Isto não só reduz os custos de hardware, mas
menos a latência média de comunicação multiplicado pelo também facilita a virtualização. Para obter um bom
número de iterações. desempenho através de memória compartilhada, no entanto,
duas alterações de hardware ainda são necessários. Primeiro,
A alternativa apresentada pelo DSWP é que, em vez de as instruções produce e consume são necessários para evitar
colocar cada iteração alternadamente em cada núcleo, DSWP os custos de implementação da sincronização em software.
quebra a iteração do loop colocando a primeira parte, Em segundo lugar, é necessário alterar o protocolo de
responsável por percorrer as estruturas de dados recursivas ou coerência de cache para realizar o encaminhamento das
ligadas, no core 0 e a segunda parte, o corpo do loop, no core linhas de cache (forwarding of cache lines) usadas para
1. Como conseqüência disto, o caminho crítico do ciclo de implementar as filas. Ter uma linha de cache transmitida do
dependências permanece no core 0 e portanto, não estará núcleo produtor, quando esta ficar cheia, elimina-se os stalls
sujeito aos atrasos provocados pela latência de comunicação. para acessar as filas no núcleo consumidor.
DSWP exige que o fluxo de dados entre os núcleos seja
acíclico. Isto implica que as instruções de cada recorrência II. O ALGORITMO DSWP
devem ser agendadas no mesmo núcleo com todas as outras O primeiro passo do algoritmo DSWP é construir o grafo de
instruções da mesma recorrência. Recorrências diferentes são dependências para o loop em questão. Neste grafo, cada
muitas vezes atribuídos a diferentes núcleos na prática, pois, vértice corresponde a uma instrução do loop e as arestas
por definição, as dependências entre eles são acíclicas. representam as dependências entre as instruções:
Claramente, esta exigência pode limitar os loops passíveis de dependências de dados, de controle e de memória, bem como
DSWP. Os autores descrevem a experiência deles em relação as dependências de malha (loop-carried dependence).
à aplicabilidade de DSWP em códigos existentes face a esta Dependências de saída e as anti-dependências podem ser
limitação e concluem que são raros em códigos após ignoradas. O segundo passo é garantir um particionamento
otimizações ILP. Alem disso, o paralelismo DOACROSS acíclico encontrando os componentes fortemente conexos
normalmente é mais restritivo. Em muitos casos, essas (SCCs) e criando um grafo dirigido acíclico a partir deles
(DAGSCC). DSWP requer que todas as instruções contidas no
O trabalho em referência foi apresentado na conferência MICRO'38 realizado mesmo SCC permaneçam na mesma thread.
entre os dias 12 e 16 de novembro de 2005 na cidade de Washington, DC, USA.
O resumo é parte do trabalho de pesquisa de doutorado do Instituto de
Computação da UNICAMP (IC-Unicamp) e foi elaborado por Pereira, M. M. (e- Os autores definem então um particionamento válido P de
mail: mpereira@ic.unicamp.br ). DAGSCC, a sequencia P1, P2, …, Pn de conjunto de vertices
2. jul-2011 2
DAGSCC (i.e. Pis são conjuntos de SCCs) satisfazendo as adicional ao número de sofisticadas técnicas de otimização
sequintes condições: ILP, incluindo Software Pipelining. O conjunto de
1. 1 ≤ n ≤ t, onde t é o número de threads que o benchmarks utilizados incluem aplicações do SPEC-
processador alvo pode executar simultaneamente; CPU2000, do Mediabench e o utilitário 'wc' do Unix. Para
2. Cada vértice em DAGSCC pertence a exatamente uma avaliar os resultados eles usaram o Itanium com 2 núcleos. A
partição em P ; matriz de sincronização tinha um total de 256 filas, cada uma
3. Para cada aresta (u→v) em DAGSCC, com u Є Pi e com 32 elementos. Um speedup de 19,4% foi alcançado em
v Є Pj, temos i ≤ j. importantes benchmarks e uma média de 9,2% foi medida
levando em conta todos os benchmarks, o que mostra,
Após a partição ser feita o algoritmo considera os custos das segundo os autores, que esta técnica é promissora.
instruções produce e consume para verificar se esta partição
é vantajosa ou não. O problema da escolha de uma partição Ainda, de acordo com os autores, outras técnicas de
válida que minimiza o custo total de exeução é um problema paralelização, não especulativas, e de propósito geral existem,
NP-completo. Na prática, são usadas heurísticas para mas normalmente estas técnicas requerem linguagens com
maximizar o balanceamento de carga entre as threads, suporte a “construções paralelas”, ou seja, o programador
computando os cíclos estimados necessários para executar precisa reescrever a aplicação para expor o paralelismo.
todas as instruções em cada SCC.
A divisão do código envolve os seguintes passos: IV. CONCLUSÃO
1. Computa-se o conjunto de blocos básicos relevantes Em adição às promessas iniciais, o artigo mostra que os
(BBs) para cada partição Pi. Este conjunto contempla todos resultados podem ser melhorados através de uma análise de
os BBs do loop original que contém as instruções atribuídas memória mais acurada, heuristicas de particionamento mais
à Pi bem como as instruções que Pi depende para permitir a elaboradas, novas otimizações para reduzir o número de
inserção das instruções produce e consume nos pontos flows, etc. Os autores acreditam que DSWP pode vir a ser um
onde os valores dependentes são definidos no código. Isto habilitador para futuras pesquisas relacionadas a TLP.
preserva as condições onde as dependências ocorrem.
2. Cria-se os BBs para o Pi.
3. Insere as instruções atribuídas à Pi no BB
correspondente, mantendo a ordem original relativa dentro V. REFERENCIAS
do bloco básico; [1] G. Ottoni, R. Rangan, A. Stoler, and D. I. August. Automatic Thread
4. Fixa-se os branch targets. Extraction with Decoupled Software Pipelining. In Proceedings of the 38th
annual IEEE/ACM International Symposium on Microarchitecture (MICRO
38). IEEE Computer Society, Washington, DC, USA, 105-118. 2005
O último passo do algoritmo DSWP é a inserção dos pares de
instruções produce e consume (chamado de flows) para
[2] R. Rangan, N. Vachharajani, A. Stoler, G. Ottoni, D. I. August, and G. Z. N.
garantir a corretude do código transformado. Os flows criados Cai. Support for high-frequency streaming in CMPs. In Proceedings of the 39th
são classificados em 3 categorias: data dependence, control International Symposium on Microarchitecture, pages 259–269, December
dependence e memory/synchronization dependence. Neste 2006.
último não há valor a ser transmitido. O mesmo é usado como
um token para reforçar as restrições de ordenação das
operações.
No DSWP, as filas são reusadas a cada iteração e,
dependendo do caminho executado, o conjunto de filas pode
variar de iteração a iteração. Para garantir a corretude, o
compilador precisa fazer com que os valores de diferentes
iterações sejam entregues corretamente. Para isto, o controle
de fluxo da thread é verificado a cada iteração. Isto requer
alguns controles de dependências adicionais, chamados loop-
iteration control dependence. Para capturar tais
dependências, conceitualmente desenrola-se a primeira
iteração do loop. O algoritmo calcula então as dependências
de controle padrão para a versão desenrolada do código para
uso no código original. O grafo de dependência de controle
resultante usado pelo DSWP é obtido pela coalescência dos
pares correspondentes de nós no grafo de dependência de
controle para o código desenrolado.
III. IMPEMENTAÇÃO E AVALIAÇÃO
Para avaliar o DSWP, os autores implementaram o algoritimo
no back-end do compilador IMPACT como um passo