Paralelização Automática de Código em Plataformas
Heterogêneas Modernas
Rogério A. Gonçalves1,2 Alfredo Goldman1
1Laborató...
Roteiro
1 Introdução
2 Conceitos
3 Abordagens sobre Paralelização
4 Transformações de Laços
5 Modelo Polyhedral
6 Ferramen...
Objetivos
Uma visão geral sobre a abordagem de paralelização
automática.
Alguns conceitos sobre o Modelo Polyhedral.
Apres...
Introdução I
Evolução e heterogeneidade das plataformas de
hardware.
Dispositivos aceleradores tem sido utilizados na
comp...
Introdução II
Plataformas vs. Aplicações
No cenário atual é evidente a grande distância entre o
potencial de desempenho di...
Paralelização de Aplicações I
Existem pelo menos duas formas de se obter aplicações
paralelas:
Concepção de aplicações par...
Paralelização de Aplicações II
No contexto de tradução de código, tem-se pelo menos
duas abordagens conhecidas de paraleli...
Aceleração de Aplicações I
A aceleração de aplicações está relacionada com as
plataformas modernas.
São plataformas hetero...
Aceleração de Aplicações II
O uso de dispositivos aceleradores torna possível a
divisão da carga de execução entre um elem...
Abordagens que se destacam
Diretivas de Compilação
Diretivas de compilação são usadas para guiar o compilador no processo ...
Diretivas de Compilação
O código é anotado com diretivas de preprocessamento
(#pragma).
Ferramentas que utilizam diretivas...
Diretivas de Compilação
Exemplo da diretiva #pragma acc kernels que define uma região de
código que será transformada em ke...
Paralelização Automática
A ideia é que o código não seja modificado, nem
anotado.
Regiões paralelizáveis detectadas automat...
Transformações de Laços I
Técnicas de otimização de laços são utilizadas por
compiladores há muito tempo.
Possibilitam a e...
Transformações de Laços II
Transformações podem ser aplicadas para: analisar,
preparar e expor algum paralelismo latente.
...
Detecção de Regiões Paralelizáveis I
No processo de paralelização de código é necessário
detectar as regiões paralelizávei...
Transformações de Laços e Modelo Polyhedral I
O Modelo Polyhedral possui um suporte melhor para a
representação e análise ...
Transformações de Laços e Modelo Polyhedral II
1 f o r ( i =1; i<=n−1; i ++) {
2 f o r ( j =1; j<=m−1; j++) {
3 A[ i ] [ j...
Transformações de Laços e Modelo Polyhedral III
Função de Scattering: c1 = i + j e c2 = i (novo domínio
de iterações).
Fig...
Transformações de Laços e Modelo Polyhedral IV
Código original e modificado com o CLooG (Skewing):
1 f o r ( i =1; i<=n−1; ...
Ferramentas que utilizam o Modelo Polyhedral I
São ferramentas que cobrem desde a extração de
regiões candidatas à paralel...
Ferramentas que utilizam o Modelo Polyhedral II
O C-to-CUDA faz a tradução source-to-source de
código C para CUDA.
PPCG us...
Por que usar LLVM? I
LLVM (llvm.org) é um projeto que fornece uma infraestrutura para a
construção de compiladores.
Desenv...
Por que usar LLVM? II
Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 24 / 55
Exemplo: LLVM IR I
Código em C.
1 i n t main ( ) {
2 i n t a , b , c ;
3 a = 5 ;
4 b = 2 ;
5 c = a + b ;
6
7 i f ( c > 5) ...
Exemplo: LLVM IR I
1 d e f i n e i32 @main ( ) #0 {
2 %1 = a l l o c a i32 , a l i g n 4
3 %a = a l l o c a i32 , a l i g ...
Exemplo: LLVM IR I
Código em C.
1 i n t funcA ( i n t x , i n t y ) {
2 i n t r e s u l t = x ∗ y ;
3 r e t u r n r e s u ...
Exemplo: LLVM IR I
Código em C.
1 i n t main ( ) {
2 i n t i ;
3 i n t r e s = 0 ;
4 f o r ( i =0; i < 100; i ++){
5 r e s...
Exemplo: LLVM IR I
1 d e f i n e i32 @main ( ) #0 {
2 %1 = a l l o c a i32 , a l i g n 4
3 %i = a l l o c a i32 , a l i g ...
Ferramentas LLVM
Projetos como o DragonEgg, PoLLy e NVPTX
possibilitam que regiões paralelizáveis sejam traduzidas
para ke...
PoLLy I
Aplica otimizações e transformações sobre o código
intermediário LLVM-IR.
Da mesma forma que outras ferramentas, o...
Gerando Código para GPU
Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 32 / 55
Exemplo Soma de Vetores I
Código do exemplo soma de vetores:
1 i n t main () {
2 i n t i ;
3 /∗ I n i c i a l i z a c a o ...
Exemplo Soma de Vetores II
Código LLVM-IR equivalente gerado:
1 @h_a = common g l o b a l [1024 x float ] zeroinitializer ...
Exemplo Soma de Vetores III
22
23 ; < l a b e l >:5 ; preds = %2
24 %6 = load i32∗ %i , a l i g n 4
25 %7 = s e x t i32 %6...
Exemplo Soma de Vetores IV
38 ; < l a b e l >:18 ; preds = %5
39 %19 = load i32∗ %i , a l i g n 4
40 %20 = add nsw i32 %19...
Exemplo Soma de Vetores V
O CFG do laço de repetição contido na função main:
Gonçalves, Goldman Paralelização Automática 1...
Exemplo Soma de Vetores VI
Laço em destaque como SCoP detectado pelo PoLLy:
Gonçalves, Goldman Paralelização Automática 17...
Exemplo Soma de Vetores VII
O PoLLy detecta as SCoPs do código que serão
traduzidas para a representação polyhedral.
O PoL...
Exemplo Soma de Vetores VIII
Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 40 / 55
Exemplo da Estrutura de um kernel para GPU
Kernel para a soma de vetores:
1 __global__ void vecAdd ( f l o a t ∗ A, f l o ...
Mapeamento de identificadores no LLVM-IR
O NVPTX fornece declarações de funções que recuperam os identificadores:
CUDA Signi...
Transformação para Kernels I
Funções de módulos LLVM-IR podem ser transformados em kernels.
Para exemplificar a transformaç...
Transformação para Kernels II
A correspondência entre os trechos de código LLVM-IR original e o
formato para o NVPTX. Tran...
Transformação para Kernels III
Sequência de passos necessários para gerar, carregar o código do
kernel e efetuar transferê...
Sequência de Passos para os Próximos Exemplos I
Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 46 / 55
Exemplo: vectorAdd (Soma de Vetores)
1 f l o a t h_a [N ] ;
2 f l o a t h_b [N ] ;
3 f l o a t h_c [N ] ;
4
5 i n t main (...
Exemplo: vectorAdd (Soma de Vetores)
Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 47 / 55
Transformação para vectoradd-kernel
Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 48 / 55
Código para o vectoradd-kernel
Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 49 / 55
Código PTX para o vectoradd-kernel
Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 50 / 55
Exemplo: sincos (Cálculo de Seno e Cosseno)
1 s u b r o u t i n e s i n c o s _ f u n c t i o n ( nx , ny ,
nz , x , y , x...
Exemplo: sincos (Cálculo de Seno e Cosseno)
Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 51 / 55
Transformação para sincos-kernel
Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 52 / 55
Código para o sincos-kernel
Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 53 / 55
Referências e Links
D. F. Bacon, S. L. Graham, O. J. Sharp, Oliver, and J. Sharp,
“Compiler Transformations for High-Perfo...
Contatos
Rogério A. Gonçalves:
rag@ime.usp.br, rogerioag@utfpr.edu.br
Alfredo Goldman:
gold@ime.usp.br
Gonçalves, Goldman ...
Próximos SlideShares
Carregando em…5
×

"Aula sobre Paralelização Automática". Rogério A. Gonçalves e Prof. Dr. Alfredo Goldman IME/USP.

168 visualizações

Publicada em

"Aula sobre Paralelização Automática", presented at http://3whpc.lcca.usp.br . llvm e paradigmas.

Publicada em: Tecnologia
0 comentários
0 gostaram
Estatísticas
Notas
  • Seja o primeiro a comentar

  • Seja a primeira pessoa a gostar disto

Sem downloads
Visualizações
Visualizações totais
168
No SlideShare
0
A partir de incorporações
0
Número de incorporações
2
Ações
Compartilhamentos
0
Downloads
3
Comentários
0
Gostaram
0
Incorporações 0
Nenhuma incorporação

Nenhuma nota no slide

"Aula sobre Paralelização Automática". Rogério A. Gonçalves e Prof. Dr. Alfredo Goldman IME/USP.

  1. 1. Paralelização Automática de Código em Plataformas Heterogêneas Modernas Rogério A. Gonçalves1,2 Alfredo Goldman1 1Laboratório de Sistemas de Software (LSS) Centro de Competência de Software Livre (CCSL) Instituto de Matemática e Estatística (IME) Universidade de São Paulo (USP) 2Departamento de Computação (DACOM) Universidade Tecnológica Federal do Paraná (UTFPR) Grupo de Computação de Alto Desempenho e Sistemas Distribuídos rogerioag@utfpr.edu.br, {rag,gold}@ime.usp.br 3o Workshop de High Performance Computing Convênio: USP – Rice University Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 1 / 55
  2. 2. Roteiro 1 Introdução 2 Conceitos 3 Abordagens sobre Paralelização 4 Transformações de Laços 5 Modelo Polyhedral 6 Ferramentas e Exemplos 7 LLVM e Ferramentas 8 Dúvidas Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 2 / 55
  3. 3. Objetivos Uma visão geral sobre a abordagem de paralelização automática. Alguns conceitos sobre o Modelo Polyhedral. Apresentar algumas ferramentas que utilizam esse modelo. Apresentar as ferramentas e projetos LLVM. Exemplos práticos indo do fonte original ao código para GPU. Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 3 / 55
  4. 4. Introdução I Evolução e heterogeneidade das plataformas de hardware. Dispositivos aceleradores tem sido utilizados na composição de supercomputadores. Não há suporte direto à reescrita de aplicações existentes. Os kits de desenvolvimento ainda não estão maduros o suficiente. Programar novas aplicações ou traduzir aplicações de código legado não é uma tarefa trivial. Ponto de vista do software. Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 4 / 55
  5. 5. Introdução II Plataformas vs. Aplicações No cenário atual é evidente a grande distância entre o potencial de desempenho disponibilizado pelas plataformas modernas e as aplicações que precisam fazer uso desse potencial. Soluções O ideal é que a ligação entre esses contextos seja feita por ferramentas de compilação e ambientes de execução. Fornecendo suporte à execução de aplicações novas e de código legado. Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 5 / 55
  6. 6. Paralelização de Aplicações I Existem pelo menos duas formas de se obter aplicações paralelas: Concepção de aplicações paralelas Adaptar aplicações existentes Nas duas formas, existe um modelo de programação que fornece suporte à escrita ou adaptação do código, e um modelo de execução que irá executar a versão paralela do código. Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 6 / 55
  7. 7. Paralelização de Aplicações II No contexto de tradução de código, tem-se pelo menos duas abordagens conhecidas de paralelização que se distinguem na forma e no momento da intervenção para paralelização: Via código fonte: depende da existência do código fonte (source-to-source). Via código binário: aplica transformações sobre o binário gerado para a execução da aplicação. (Tradução Dinâmica - DBT). Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 7 / 55
  8. 8. Aceleração de Aplicações I A aceleração de aplicações está relacionada com as plataformas modernas. São plataformas heterogêneas, que congregam diversas tecnologias e seus elementos de processamento que trabalham como aceleradores na execução de aplicações. Como exemplos dos dispositivos que atualmente compõem essas plataformas temos os arranjos de coprocessadores Xeon Phi (Intel), as GPUs (NVidia, AMD) e FPGAS (Xilinx, Altera). Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 8 / 55
  9. 9. Aceleração de Aplicações II O uso de dispositivos aceleradores torna possível a divisão da carga de execução entre um elemento de processamento principal e elementos que irão trabalhar como coprocessadores. Regiões de código paralelizáveis podem ser transformadas em kernels e terem sua execução acelerada em uma GPU. Ex.: Laços. Trabalhos tem proposto modelos para a execução de aplicações combinando dispositivos multicore e multiGPU. Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 9 / 55
  10. 10. Abordagens que se destacam Diretivas de Compilação Diretivas de compilação são usadas para guiar o compilador no processo de tradução e paralelização de código. Paralelização Automática São usadas técnicas e modelos para detectar automaticamente quais regiões do código são paralelizáveis. Nas duas abordagens uma versão paralela do código é gerada para a plataforma alvo. Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 10 / 55
  11. 11. Diretivas de Compilação O código é anotado com diretivas de preprocessamento (#pragma). Ferramentas que utilizam diretivas O OpenMP (multicore). O hiCUDA (transformar e gerar código para CUDA). O CGCM (otimiza a comunicação e transferências de dados). Os compiladores PGI e o OpenHMPP que implementam o padrão OpenACC. O accULL é uma implementação do padrão OpenACC com suporte a CUDA e a OpenCL. O OpenMC é uma extensão do OpenMP para suporte a GPU. Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 11 / 55
  12. 12. Diretivas de Compilação Exemplo da diretiva #pragma acc kernels que define uma região de código que será transformada em kernels. 1 #pragma acc data copy ( b [ 0 : n∗m] ) c r e a t e ( a [ 0 : n∗m] ) 2 { 3 f o r ( i t e r = 1; i t e r <= p ; ++i t e r ) { 4 #pragma acc k e r n e l s 5 { 6 f o r ( i = 1; i < n−1; ++i ) 7 f o r ( j = 1; j < m−1; ++j ) { 8 /∗ Suprimido . ∗/ 9 } 10 f o r ( i = 1; i < n−1; ++i ) 11 f o r ( j = 1; j < m−1; ++j ) 12 /∗ Suprimido . ∗/ 13 } 14 } 15 } Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 12 / 55
  13. 13. Paralelização Automática A ideia é que o código não seja modificado, nem anotado. Regiões paralelizáveis detectadas automaticamente. Ferramentas da abordagem automática Par4All (análise interprocedural) C-to-CUDA PPCG KernelGen Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 13 / 55
  14. 14. Transformações de Laços I Técnicas de otimização de laços são utilizadas por compiladores há muito tempo. Possibilitam a exploração de processamento paralelo e reduzem o tempo de execução associado aos laços. A análise de dependência deve ser feita sobre todas as iterações do laço. Uma transformação aplicada deve preservar a semântica do código original e a sequência temporal de todas as dependências. Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 14 / 55
  15. 15. Transformações de Laços II Transformações podem ser aplicadas para: analisar, preparar e expor algum paralelismo latente. Exemplos loop unrolling, loop interchange, loop skewing, loop reversal, loop blocking e cycle shrinking, loop fusion, peeling e distribuição, entre outras. Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 15 / 55
  16. 16. Detecção de Regiões Paralelizáveis I No processo de paralelização de código é necessário detectar as regiões paralelizáveis. Essas regiões são chamadas de Static Control Parts (SCoPs). São partes do código de uma função que podem ser vistas como uma estrutura de fluxo de controle que contem apenas laços FOR e IFs. Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 16 / 55
  17. 17. Transformações de Laços e Modelo Polyhedral I O Modelo Polyhedral possui um suporte melhor para a representação e análise de código de laços do que a AST. A representação de SCoPs no modelo baseia-se nos conceitos: domínio de iteração, função de scattering e função de acesso. Encontrando-se um SCoP, a região de código pode ser representada no modelo e transformações e otimizações podem ser aplicadas à representação gerada. Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 17 / 55
  18. 18. Transformações de Laços e Modelo Polyhedral II 1 f o r ( i =1; i<=n−1; i ++) { 2 f o r ( j =1; j<=m−1; j++) { 3 A[ i ] [ j ] = (A[ i −1][ j ] + A[ i ] [ j −1] + A[ i +1][ j ] + A[ i ] [ j +1]) /4; 4 } 5 } Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 18 / 55
  19. 19. Transformações de Laços e Modelo Polyhedral III Função de Scattering: c1 = i + j e c2 = i (novo domínio de iterações). Figura 3: Domínio de Iteração DS1 = {(i, j) ∈ Z2|1 ≤ i ≤ n−1∧1 ≤ j ≤ m−1} Figura 4: Função de Scattering θS1(i, j) = (i + j, i) θS1(i, j) = (c1, c2) c1 = i + j c2 = i Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 19 / 55
  20. 20. Transformações de Laços e Modelo Polyhedral IV Código original e modificado com o CLooG (Skewing): 1 f o r ( i =1; i<=n−1; i ++) { 2 f o r ( j =1; j<=m−1; j ++) { 3 A[ i ] [ j ] = (A[ i −1][ j ] + A[ i ] [ j −1] + A[ i +1][ j ] + A[ i ] [ j +1]) / 4 ; // S1 4 } 5 } Substituindo as variáveis: i = c2 e j = c1 − i = c1 − c2, tem-se o código final: 1 i f ((m >= 2) && ( n >= 2) ) { 2 f o r ( c1=2;c1<=n+m−2;c1++) { 3 f o r ( c2=max(1 , c1−m+1) ; c2<=min ( c1 −1,n−1) ; c2++) { 4 A[ c2 ] [ c1−c2 ] = (A[ c2 −1][ c1−c2 ] + A[ c2 ] [ c1−c2 −1] + A[ c2 +1][ c1−c2 ] + A[ c2 ] [ c1−c2 +1]) /4; //S1 ’ 5 } 6 } 7 } Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 20 / 55
  21. 21. Ferramentas que utilizam o Modelo Polyhedral I São ferramentas que cobrem desde a extração de regiões candidatas à paralelização, passando por bibliotecas que permitem o uso como subprojetos até geradores de código com base em informações do Modelo Polyhedral. Ferramentas que extraem SCoPs: clan e pet. Gerador de Código para C: CLooG. Compiladores como PLuTo e PoCC fazem tradução source-to-source de código C e Fortran. Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 21 / 55
  22. 22. Ferramentas que utilizam o Modelo Polyhedral II O C-to-CUDA faz a tradução source-to-source de código C para CUDA. PPCG usa as bibliotecas pet e isl para gerar código OpenMP e CUDA. O PoLLy é um projeto LLVM que implementa o modelo polyhedral para código intermediário (LLVM-IR). Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 22 / 55
  23. 23. Por que usar LLVM? I LLVM (llvm.org) é um projeto que fornece uma infraestrutura para a construção de compiladores. Desenvolvimento: LLVM Team - University of Illinois at Urbana-Champaign. Licença: University of Illinois/NCSA Open Source License, certificada pela OSI. Sua organização modular facilita o reuso no desenvolvimento de ferramentas de compilação. Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 23 / 55
  24. 24. Por que usar LLVM? II Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 24 / 55
  25. 25. Exemplo: LLVM IR I Código em C. 1 i n t main ( ) { 2 i n t a , b , c ; 3 a = 5 ; 4 b = 2 ; 5 c = a + b ; 6 7 i f ( c > 5) { 8 c = 2 ∗ c ; 9 } 10 e l s e { 11 c = 3 ∗ c ; 12 } 13 14 r e t u r n 0 ; 15 } Código em LLVM-IR. 1 d e f i n e i32 @main ( ) #0 { 2 %1 = a l l o c a i32 , a l i g n 4 3 %a = a l l o c a i32 , a l i g n 4 4 %b = a l l o c a i32 , a l i g n 4 5 %c = a l l o c a i32 , a l i g n 4 6 s t o r e i32 0 , i32 ∗ %1 7 s t o r e i32 5 , i32 ∗ %a, a l i g n 4 8 s t o r e i32 2 , i32 ∗ %b, a l i g n 4 9 %2 = l o a d i32 ∗ %a, a l i g n 4 10 %3 = l o a d i32 ∗ %b, a l i g n 4 11 %4 = add nsw i32 %2, %3 12 s t o r e i32 %4, i32 ∗ %c, a l i g n 4 13 %5 = l o a d i32 ∗ %c, a l i g n 4 14 %6 = icmp s g t i32 %5, 5 15 br i1 %6, l a b e l %vv , l a b e l %ff 16 17 vv : ; preds = %0 18 %7 = l o a d i32 ∗ %c, a l i g n 4 19 %8 = mul nsw i32 2 , %7 20 s t o r e i32 %8, i32 ∗ %c, a l i g n 4 21 br l a b e l %fim 22 23 ff : ; preds = %0 24 %9 = l o a d i32 ∗ %c, a l i g n 4 25 %10 = mul nsw i32 3 , %9 26 s t o r e i32 %10 , i32 ∗ %c, a l i g n 4 27 br l a b e l %fim 28 29 fim : ; preds = %vv, %ff 30 r e t i32 0 31 } Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 25 / 55
  26. 26. Exemplo: LLVM IR I 1 d e f i n e i32 @main ( ) #0 { 2 %1 = a l l o c a i32 , a l i g n 4 3 %a = a l l o c a i32 , a l i g n 4 4 %b = a l l o c a i32 , a l i g n 4 5 %c = a l l o c a i32 , a l i g n 4 6 s t o r e i32 0 , i32 ∗ %1 7 s t o r e i32 5 , i32 ∗ %a, a l i g n 4 8 s t o r e i32 2 , i32 ∗ %b, a l i g n 4 9 %2 = l o a d i32 ∗ %a, a l i g n 4 10 %3 = l o a d i32 ∗ %b, a l i g n 4 11 %4 = add nsw i32 %2, %3 12 s t o r e i32 %4, i32 ∗ %c, a l i g n 4 13 %5 = l o a d i32 ∗ %c, a l i g n 4 14 %6 = icmp s g t i32 %5, 5 15 br i1 %6, l a b e l %vv , l a b e l %ff 16 17 vv : ; preds = %0 18 %7 = l o a d i32 ∗ %c, a l i g n 4 19 %8 = mul nsw i32 2 , %7 20 s t o r e i32 %8, i32 ∗ %c, a l i g n 4 21 br l a b e l %fim 22 23 ff : ; preds = %0 24 %9 = l o a d i32 ∗ %c, a l i g n 4 25 %10 = mul nsw i32 3 , %9 26 s t o r e i32 %10 , i32 ∗ %c, a l i g n 4 27 br l a b e l %fim 28 29 fim : ; preds = %vv, %ff 30 r e t i32 0 31 } Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 26 / 55
  27. 27. Exemplo: LLVM IR I Código em C. 1 i n t funcA ( i n t x , i n t y ) { 2 i n t r e s u l t = x ∗ y ; 3 r e t u r n r e s u l t ; 4 } 5 6 i n t main ( ) { 7 i n t a , b , c ; 8 a = 5 ; 9 c = funcA ( a , 2) ; 10 11 r e t u r n 0 ; 12 } Código em LLVM-IR. 1 d e f i n e i32 @funcA ( i32 %x, i32 %y) #0 { 2 %1 = a l l o c a i32 , a l i g n 4 3 %2 = a l l o c a i32 , a l i g n 4 4 % r e s u l t = a l l o c a i32 , a l i g n 4 5 s t o r e i32 %x, i32 ∗ %1, a l i g n 4 6 s t o r e i32 %y, i32 ∗ %2, a l i g n 4 7 %3 = l o a d i32 ∗ %1, a l i g n 4 8 %4 = l o a d i32 ∗ %2, a l i g n 4 9 %5 = mul nsw i32 %3, %4 10 s t o r e i32 %5, i32 ∗ %result , a l i g n 4 11 %6 = l o a d i32 ∗ %result , a l i g n 4 12 r e t i32 %6 13 } 14 d e f i n e i32 @main ( ) #0 { 15 %1 = a l l o c a i32 , a l i g n 4 16 %a = a l l o c a i32 , a l i g n 4 17 %b = a l l o c a i32 , a l i g n 4 18 %c = a l l o c a i32 , a l i g n 4 19 s t o r e i32 0 , i32 ∗ %1 20 s t o r e i32 5 , i32 ∗ %a, a l i g n 4 21 %2 = l o a d i32 ∗ %a, a l i g n 4 22 %3 = c a l l i32 @funcA ( i32 %2, i32 2) 23 s t o r e i32 %3, i32 ∗ %c, a l i g n 4 24 r e t i32 0 25 } Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 27 / 55
  28. 28. Exemplo: LLVM IR I Código em C. 1 i n t main ( ) { 2 i n t i ; 3 i n t r e s = 0 ; 4 f o r ( i =0; i < 100; i ++){ 5 r e s = r e s + i ; 6 } 7 8 r e t u r n 0 ; 9 } Código em LLVM-IR. 1 d e f i n e i32 @main ( ) #0 { 2 %1 = a l l o c a i32 , a l i g n 4 3 %i = a l l o c a i32 , a l i g n 4 4 %res = a l l o c a i32 , a l i g n 4 5 s t o r e i32 0 , i32 ∗ %1 6 s t o r e i32 0 , i32 ∗ %res , a l i g n 4 7 s t o r e i32 0 , i32 ∗ %i , a l i g n 4 8 br l a b e l %2 9 10 ; < label >:2 ; preds = %9, %0 11 %3 = l o a d i32 ∗ %i , a l i g n 4 12 %4 = icmp s l t i32 %3, 100 13 br i1 %4, l a b e l %5, l a b e l %12 14 15 ; < label >:5 ; preds = %2 16 %6 = l o a d i32 ∗ %res , a l i g n 4 17 %7 = l o a d i32 ∗ %i , a l i g n 4 18 %8 = add nsw i32 %6, %7 19 s t o r e i32 %8, i32 ∗ %res , a l i g n 4 20 br l a b e l %9 21 22 ; < label >:9 ; preds = %5 23 %10 = l o a d i32 ∗ %i , a l i g n 4 24 %11 = add nsw i32 %10 , 1 25 s t o r e i32 %11 , i32 ∗ %i , a l i g n 4 26 br l a b e l %2 27 28 ; < label >:12 ; preds = %2 29 r e t i32 0 30 } Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 28 / 55
  29. 29. Exemplo: LLVM IR I 1 d e f i n e i32 @main ( ) #0 { 2 %1 = a l l o c a i32 , a l i g n 4 3 %i = a l l o c a i32 , a l i g n 4 4 %res = a l l o c a i32 , a l i g n 4 5 s t o r e i32 0 , i32 ∗ %1 6 s t o r e i32 0 , i32 ∗ %res , a l i g n 4 7 s t o r e i32 0 , i32 ∗ %i , a l i g n 4 8 br l a b e l %2 9 10 ; < label >:2 ; preds = %9, %0 11 %3 = l o a d i32 ∗ %i , a l i g n 4 12 %4 = icmp s l t i32 %3, 100 13 br i1 %4, l a b e l %5, l a b e l %12 14 15 ; < label >:5 ; preds = %2 16 %6 = l o a d i32 ∗ %res , a l i g n 4 17 %7 = l o a d i32 ∗ %i , a l i g n 4 18 %8 = add nsw i32 %6, %7 19 s t o r e i32 %8, i32 ∗ %res , a l i g n 4 20 br l a b e l %9 21 22 ; < label >:9 ; preds = %5 23 %10 = l o a d i32 ∗ %i , a l i g n 4 24 %11 = add nsw i32 %10 , 1 25 s t o r e i32 %11 , i32 ∗ %i , a l i g n 4 26 br l a b e l %2 27 28 ; < label >:12 ; preds = %2 29 r e t i32 0 30 } Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 29 / 55
  30. 30. Ferramentas LLVM Projetos como o DragonEgg, PoLLy e NVPTX possibilitam que regiões paralelizáveis sejam traduzidas para kernels que possam ter sua execução lançada em GPUs. DragonEgg: Plugin para GCC que traduz código intermediário (GIMPLE) para a representação intermediária do LLVM (LLVM-IR). PoLLy: Implementação do Modelo Polyhedral para LLVM. NVPTX: Backend do LLVM para gerar código PTX (intermediário das GPUs da NVIDIA). Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 30 / 55
  31. 31. PoLLy I Aplica otimizações e transformações sobre o código intermediário LLVM-IR. Da mesma forma que outras ferramentas, o PoLLy trabalha com (SCoPs). O PoLLy implementa um conjunto de passos que detectam e traduzem essas partes do código para a representação do modelo polyhedral para que possam ser aplicadas análises e transformações, e o código LLVM-IR otimizado gerado. Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 31 / 55
  32. 32. Gerando Código para GPU Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 32 / 55
  33. 33. Exemplo Soma de Vetores I Código do exemplo soma de vetores: 1 i n t main () { 2 i n t i ; 3 /∗ I n i c i a l i z a c a o dos v e t o r e s . ∗/ 4 i n i t _ a r r a y () ; 5 6 /∗ Calculo . ∗/ 7 f o r ( i = 0; i < N; i++) { 8 h_c [ i ] = h_a [ i ] + h_b [ i ] ; 9 } 10 11 /∗ Resultados . ∗/ 12 print_array () ; 13 check_result () ; 14 15 r e t u r n 0; 16 } Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 33 / 55
  34. 34. Exemplo Soma de Vetores II Código LLVM-IR equivalente gerado: 1 @h_a = common g l o b a l [1024 x float ] zeroinitializer , a l i g n 16 2 @h_b = common g l o b a l [1024 x float ] zeroinitializer , a l i g n 16 3 @h_c = common g l o b a l [1024 x float ] zeroinitializer , a l i g n 16 4 d e f i n e void @init_array () #0 { 5 } 6 d e f i n e void @print_array () #0 { 7 } 8 d e f i n e void @check_result () #0 { 9 } 10 d e f i n e i32 @main () #0 { 11 %1 = a l l o c a i32 , a l i g n 4 12 %i = a l l o c a i32 , a l i g n 4 13 s t o r e i32 0 , i32∗ %1 14 c a l l void @init_array () 15 s t o r e i32 0 , i32∗ %i , a l i g n 4 16 br l a b e l %2 17 18 ; <label >:2 ; preds = %18, %0 19 %3 = load i32∗ %i , a l i g n 4 20 %4 = icmp s l t i32 %3, 1024 21 br i1 %4, l a b e l %5, l a b e l %21 Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 34 / 55
  35. 35. Exemplo Soma de Vetores III 22 23 ; < l a b e l >:5 ; preds = %2 24 %6 = load i32∗ %i , a l i g n 4 25 %7 = s e x t i32 %6 to i64 26 %8 = g e t e l e m e n t p t r inbounds [1024 x float ]∗ @h_a , i32 0 , ← i64 %7 27 %9 = load float∗ %8, a l i g n 4 28 %10 = load i32∗ %i , a l i g n 4 29 %11 = s e x t i32 %10 to i64 30 %12 = g e t e l e m e n t p t r inbounds [1024 x float ]∗ @h_b , i32 0 , ← i64 %11 31 %13 = load float∗ %12 , a l i g n 4 32 %14 = fadd float %9, %13 33 %15 = load i32∗ %i , a l i g n 4 34 %16 = s e x t i32 %15 to i64 35 %17 = g e t e l e m e n t p t r inbounds [1024 x float ]∗ @h_c , i32 0 , ← i64 %16 36 s t o r e float %14 , float∗ %17 , a l i g n 4 37 br l a b e l %18 Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 35 / 55
  36. 36. Exemplo Soma de Vetores IV 38 ; < l a b e l >:18 ; preds = %5 39 %19 = load i32∗ %i , a l i g n 4 40 %20 = add nsw i32 %19 , 1 41 s t o r e i32 %20 , i32∗ %i , a l i g n 4 42 br l a b e l %2 43 44 ; <label >:21 ; preds = %2 45 c a l l void @print_array () 46 c a l l void @check_result () 47 r e t i32 0 48 } Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 36 / 55
  37. 37. Exemplo Soma de Vetores V O CFG do laço de repetição contido na função main: Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 37 / 55
  38. 38. Exemplo Soma de Vetores VI Laço em destaque como SCoP detectado pelo PoLLy: Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 38 / 55
  39. 39. Exemplo Soma de Vetores VII O PoLLy detecta as SCoPs do código que serão traduzidas para a representação polyhedral. O PoLLy pode ser usado para separar o código em blocos independentes. Visualização do código com blocos independentes que foram separados pelo PoLLy. O SCoP continua sendo o mesmo, porém foi alterado internamente, com a recuperação dos ponteiros para elementos dos arranjos sendo feita no início do corpo do laço. Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 39 / 55
  40. 40. Exemplo Soma de Vetores VIII Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 40 / 55
  41. 41. Exemplo da Estrutura de um kernel para GPU Kernel para a soma de vetores: 1 __global__ void vecAdd ( f l o a t ∗ A, f l o a t ∗ B, f l o a t ∗ C, i n t n ) { 2 i n t i d = blockDim . x ∗ b l o c k I d x . x + t h r e a d I d x . x ; 3 i f ( i d < n ) { 4 C[ i d ] = A[ i d ] + B[ i d ] ; 5 } 6 } 7 8 i n t main () { 9 /∗ . . . ∗/ 10 i n t threadsPerBlock = 256; 11 i n t b l o c k s P e r G r i d =(N + threadsPerBlock − 1) / threadsPerBlock ; 12 vecAdd<<<blocksPerGrid , threadsPerBlock >>>(d_A, d_B, d_C, N) ; 13 /∗ . . . ∗/ 14 } Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 41 / 55
  42. 42. Mapeamento de identificadores no LLVM-IR O NVPTX fornece declarações de funções que recuperam os identificadores: CUDA Significado LLVM-IR para o NVPTX threadIdx.x Id da Thread na dim. x declare i32 @llvm.nvvm.read.ptx.sreg.tid.x() threadIdx.y Id da Thread na dim. y declare i32 @llvm.nvvm.read.ptx.sreg.tid.y() threadIdx.z Id da Thread na dim. z declare i32 @llvm.nvvm.read.ptx.sreg.tid.z() blockIdx.x Id do Bloco na dim. x declare i32 @llvm.nvvm.read.ptx.sreg.ctaid.x() blockIdx.y Id do Bloco na dim. y declare i32 @llvm.nvvm.read.ptx.sreg.ctaid.y() blockIdx.z Id do Bloco na dim. z declare i32 @llvm.nvvm.read.ptx.sreg.ctaid.z() blockDim.x Dimensão x do Bloco declare i32 @llvm.nvvm.read.ptx.sreg.ntid.x() blockDim.y Dimensão y do Bloco declare i32 @llvm.nvvm.read.ptx.sreg.ntid.y() blockDim.z Dimensão z do Bloco declare i32 @llvm.nvvm.read.ptx.sreg.ntid.z() gridDim.x Dimensão x do Grid declare i32 @llvm.nvvm.read.ptx.sreg.nctaid.x() gridDim.y Dimensão y do Grid declare i32 @llvm.nvvm.read.ptx.sreg.nctaid.y() gridDim.z Dimensão z do Grid declare i32 @llvm.nvvm.read.ptx.sreg.nctaid.z() warp size Tamanho do warp declare i32 @llvm.nvvm.read.ptx.sreg.warpsize() Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 42 / 55
  43. 43. Transformação para Kernels I Funções de módulos LLVM-IR podem ser transformados em kernels. Para exemplificar a transformação de funções para a estrutura de kernels, consideremos o exemplo soma de vetores. Tanto o CFG da função principal (main), quanto a função sum_vectors(). Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 43 / 55
  44. 44. Transformação para Kernels II A correspondência entre os trechos de código LLVM-IR original e o formato para o NVPTX. Transformação da função sum_vectors para kernel: Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 44 / 55
  45. 45. Transformação para Kernels III Sequência de passos necessários para gerar, carregar o código do kernel e efetuar transferências: 1 v o i d sum_vectors ( ) { 2 /∗ Gerando o PTX. ∗/ 3 char ∗ ptx = generatePTX ( l l , s i z e ) ; 4 /∗ Criando um c o n t e x t o . ∗/ 5 cuCtxCreate (&cudaContext , 0 , cudaDevice ) ; 6 /∗ Carregando o modulo . ∗/ 7 cuModuleLoadDataEx(&cudaModule , ptx , 0 , 0 , 0) ; 8 /∗ Recuperando a funcao k e r n e l . ∗/ 9 cuModuleGetFunction (& k e r n e l F u n c t i o n , cudaModule , " sum_kernel " ) ; 10 /∗ T r a n s f e r i n d o os dados para a memoria do d i s p o s i t i v o . ∗/ 11 cuMemcpyHtoD ( devBufferA , &hostA [ 0 ] , s i z e o f ( f l o a t ) ∗N) ; 12 cuMemcpyHtoD ( devBufferB , &hostB [ 0 ] , s i z e o f ( f l o a t ) ∗N) ; 13 /∗ D e f i n i c a o das dimensoes do a r r a n j o de t h r e a d s . ∗/ 14 c a l c u l a t e D i m e n s i o n s (& blockSizeX , &blockSizeY , &blockSizeZ , &g r i d S i z e X , & g r i d S i z e Y , &g r i d S i z e Z ) ; 15 /∗ Parametros da funcao k e r n e l . ∗/ 16 v o i d ∗ kernelParams [ ] = { &devBufferA , &devBufferB , &devBufferC } ; 17 /∗ Lancando a execucao do k e r n e l . ∗/ 18 cuLaunchKernel ( k e r n e l F u n c t i o n , g r i d S i z e X , g r i d S i z e Y , g r i d S i z e Z , blockSizeX , blockSizeY , blockSizeZ , 0 , NULL , kernelParams , NULL) ; 19 /∗ Recuperando o r e s u l t a d o . ∗/ 20 cuMemcpyDtoH(&hostC [ 0 ] , devBufferC , s i z e o f ( f l o a t ) ∗N) ; 21 r e t u r n 0 ; 22 } Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 45 / 55
  46. 46. Sequência de Passos para os Próximos Exemplos I Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 46 / 55
  47. 47. Exemplo: vectorAdd (Soma de Vetores) 1 f l o a t h_a [N ] ; 2 f l o a t h_b [N ] ; 3 f l o a t h_c [N ] ; 4 5 i n t main ( ) { 6 i n t i ; 7 /∗ I n i c i a l i z a c a o dos v e t o r e s . ∗/ 8 i n i t _ a r r a y ( ) ; 9 10 /∗ C a l c u l o . ∗/ 11 f o r ( i = 0 ; i < N; i ++) { 12 h_c [ i ] = h_a [ i ] + h_b [ i ] ; 13 } 14 15 /∗ R e s u l t a d o s . ∗/ 16 p r i n t _ a r r a y ( ) ; 17 c h e c k _ r e s u l t ( ) ; 18 19 r e t u r n 0 ; 20 } Código em C. Transformada em LLVM-IR. (Fase 1) SCoP detectado pelo PoLLy (Fases 2, 3 e 4). Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 47 / 55
  48. 48. Exemplo: vectorAdd (Soma de Vetores) Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 47 / 55
  49. 49. Transformação para vectoradd-kernel Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 48 / 55
  50. 50. Código para o vectoradd-kernel Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 49 / 55
  51. 51. Código PTX para o vectoradd-kernel Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 50 / 55
  52. 52. Exemplo: sincos (Cálculo de Seno e Cosseno) 1 s u b r o u t i n e s i n c o s _ f u n c t i o n ( nx , ny , nz , x , y , xy ) 2 3 i m p l i c i t none 4 5 i n t e g e r , i n t e n t ( i n o u t ) : : nx , ny , nz 6 r e a l , i n t e n t ( i n ) : : x ( nx , ny , nz ) , y ( nx , ny , nz ) 7 r e a l , i n t e n t ( i n o u t ) : : xy ( nx , ny , nz ) 8 9 i n t e g e r : : i , j , k 10 11 do k = 1 , nz 12 do j = 1 , ny 13 do i = 1 , nx 14 xy ( i , j , k ) = s i n ( x ( i , j , k ) ) + cos ( y ( i , j , k ) ) 15 enddo 16 enddo 17 enddo 18 19 end s u b r o u t i n e s i n c o s _ f u n c t i o n Rotina em Fortran + Código Principal em C. Transformada em LLVM-IR. (Fase 1) SCoP detectado pelo PoLLy (Fases 2, 3 e 4). Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 51 / 55
  53. 53. Exemplo: sincos (Cálculo de Seno e Cosseno) Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 51 / 55
  54. 54. Transformação para sincos-kernel Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 52 / 55
  55. 55. Código para o sincos-kernel Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 53 / 55
  56. 56. Referências e Links D. F. Bacon, S. L. Graham, O. J. Sharp, Oliver, and J. Sharp, “Compiler Transformations for High-Performance Computing,” ACM Comput. Surv., vol. 26, no. 4, pp. 345–420, Nov. 1994. M. Benabderrahmane, L.-N. Pouchet, A. Cohen, and C. Bastoul, “The Polyhedral Model is More Widely Applicable Than You Think,” in Proceedings of the 19th Joint European Conference on Theory and Practice of Software, International Conference on Compiler Construction, 2010, pp. 283–303. LLVM: http://llvm.org PoLLy: htpp://polly.llvm.org NVPTX: http://llvm.org/docs/NVPTXUsage.html Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 54 / 55
  57. 57. Contatos Rogério A. Gonçalves: rag@ime.usp.br, rogerioag@utfpr.edu.br Alfredo Goldman: gold@ime.usp.br Gonçalves, Goldman Paralelização Automática 17 de abril de 2015 55 / 55

×