metodologia para paralelizaÇÃo de programas...
TRANSCRIPT
INPE-14474-TDI/1155
METODOLOGIA PARA PARALELIZAÇÃO DE PROGRAMAS CIENTÍFICOS
Simone Shizue Tomita
Dissertação de Mestrado do Curso de Pós-Graduação em Computação Aplicada, orientada pelos Drs. Haroldo Fraga de Campos Velho e Jairo Panetta, aprovada em 10
de fevereiro de 2004.
INPE São José dos Campos
2007
Publicado por: esta página é responsabilidade do SID Instituto Nacional de Pesquisas Espaciais (INPE) Gabinete do Diretor – (GB) Serviço de Informação e Documentação (SID) Caixa Postal 515 – CEP 12.245-970 São José dos Campos – SP – Brasil Tel.: (012) 3945-6911 Fax: (012) 3945-6919 E-mail: [email protected] Solicita-se intercâmbio We ask for exchange Publicação Externa – É permitida sua reprodução para interessados.
INPE-14474-TDI/1155
METODOLOGIA PARA PARALELIZAÇÃO DE PROGRAMAS CIENTÍFICOS
Simone Shizue Tomita
Dissertação de Mestrado do Curso de Pós-Graduação em Computação Aplicada, orientada pelos Drs. Haroldo Fraga de Campos Velho e Jairo Panetta, aprovada em 10
de fevereiro de 2004.
INPE São José dos Campos
2007
681.322 Tomita, S. S. Metodologia para paralelização de programas científicos / Simone Shizue Tomita. - São José dos Campos: INPE, 2004. 96p. ; – (INPE-14474-TDI/1155) 1. Processamento paralelo. 2. Programas científicos. 3. Otimização. 4. Previsão do tempo. 5. Computação. I. Título.
“A sabedoria da vida não está em só fazer aquilo que se gosta, mas também de gostar daquilo que se faz”.
LEONARDO DA VINCI
a meus filhos, GIOVANNA SHIZUE TOMITA LIMA e
GUILHERME MASSAO TOMITA LIMA.
AGRADECIMENTOS
Agradeço a meus pais, Tomita e Irene, pela base de vida que me deram e pela orientação que me fizeram seguir esse caminho. Ao Paulinho, meu esposo, pela paciência, pela força e pelo bom humor ao mostrar que as dificuldades sempre serão vencidas. E a meus filhos pela compreensão pelo tempo que deixei de compartilhar com eles. Ao Dr. José Paulo Bonatti pelo grande incentivo em iniciar e concluir esse trabalho. A sua autorização e compreensão tornaram possível esse trabalho. Aos meus amigos do coração: Luiz Flávio Rodrigues, pelo seu companheirismo e bom humor, pela colaboração no processo inicial do trabalho, e também por compartilhar sua experiência profissional e de vida; Júlio Tota, pelo companheirismo incansável e dedicação, compartilhou experiências de vida e me ensinou conceitos na área de meteorologia, essenciais na complementação desse trabalho; Dr. Álvaro Fazenda pelo auxílio na concepção de idéias e na visão crítica do contexto. Dr. Luciano P. Pezzi pela colaboração e pela amizade; Jonas Tamaoki, pela amizade e paciência no auxílio à utilização de ferramentas e mecanismos do supercomputador. Ao Centro de Previsão de Tempo e Estudos Climáticos - CPTEC / INPE pelo uso das máquinas e ferramentas de trabalho. Aos professores do INPE pelo conhecimento compartilhado, em especial ao orientador Prof. Dr. Haroldo Fraga de Campos Velho pela orientação, estímulo no trabalho e suas idéias inovadoras. Agradeço especialmente ao meu orientador de pesquisa Dr. Jairo Panetta, meu mentor, pela extrema paciência e dedicação na orientação desse trabalho, e pelo conhecimento compartilhado. Esse trabalho só tornou-se possível pela sua grande experiência profissional e grande presença de espírito. A ele meu respeito e admiração.
RESUMO
Este trabalho propõe uma nova metodologia para paralelização de programas científicos e sua aplicação a um problema real. Visa direcionar o trabalho do programador da área de processamento de alto desempenho. Essa metodologia mostra os requisitos básicos e as técnicas necessárias para transformar programas seqüenciais em programas paralelizados. Demonstra as formas de medir desempenho e avaliar os resultados numéricos ao final de cada etapa quando se aplica gradativamente a estratégia de paralelização. A metodologia é dividida em quatro passos que são: preliminares, análise do problema, estratégia geral de paralelização e análise dos resultados. A metodologia foi aplicada ao modelo regional de previsão de tempo – Eta usando uma máquina de arquitetura vetorial e paralela de memória compartilhada NEC/SX4 e arquitetura híbrida NEC/SX6 no CPTEC/INPE. O programa original era codificado em Fortran 77 e inicialmente foi transformado em Fortran 90. Em seguida houve a reestruturação do programa para permitir o paralelismo de dois níveis – vetorização e paralelismo implementado por diretivas (padrão OpenMP). A implementação foi baseada em paralelismo de dados, e resultou um programa portátil com paralelismo também portátil para máquinas de memória compartilhada. Com o objetivo de facilitar o trabalho do programador na aplicação de paralelismo em programas, a metodologia propõe um caminho menos custoso e que requer menor tempo na fase de inicialização do processo de paralelização.
SCIENTIFIC PROGRAMS PARALLELIZATION METHODOLOGY
ABSTRACT
This project is proposing a new methodology on the scientific program parallelism and applications on a real problem. It is a goal, direct the high performance processing programmer’s work. This methodology shows the basic techniques and requirements needed to convert sequential onto parallel codes. It does show the skill and evaluate the numerical results at the end of each stage when gradually the parallelism technique is applied. The methodology is divided in four steps: preliminaries, analysis of the problem, global strategy of parallelism and results analysis. The methodology has been applied to the regional weather forecast model – Eta using both vectorial and parallel architecture machine with shared memory NEC/SX4 and hybrid architecture NEC/SX6 at CPTEC/INPE. The original code was built in Fortran 77 and re-written in Fortran 90. Afterwards, the code was re-structured to allow the parallelism in two levels – vectorization and parallelism based on directives (OpenMP standard). The implementation is based on data parallelism and has resulted in a portable program with portable parallelism to shared memory machines. As an aim to turn the programmer’s job easier on the code parallelism, this methodology purposes an economical way where less effort is made in the initialisation stage of the parallelism process.
SUMÁRIO
Pág.
LISTA DE FIGURAS
LISTA DE TABELAS
LISTA DE SIGLAS E ABREVIATURAS
CAPÍTULO 1 - INTRODUÇÃO ..................................................................... 23
1.1 - Trabalhos Similares ................................................................................... 24
1.2 - Nomenclatura ............................................................................................. 24
1.3 - Estrutura da Dissertação ............................................................................ 25
CAPÍTULO 2 - PROCESSAMENTO PARALELO ..................................... 27
2.1 - Introdução .................................................................................................. 27
2.2 - Arquiteturas de Máquinas Paralelas .......................................................... 27
2.2.1 - Arquiteturas de Memória Compartilhada .................................................. 28
2.2.2 - Arquiteturas de Memória Distribuída ........................................................ 29
2.2.3 - Arquiteturas Híbridas ................................................................................. 30
2.3 - Modelos de Programação Paralela ............................................................. 30
2.3.1 - Fork-join .................................................................................................... 31
2.3.2 - Troca de Mensagens .................................................................................. 32
2.4 - OpenMP ..................................................................................................... 32
2.5 - MPI ............................................................................................................ 34
CAPÍTULO 3 - ANÁLISE DE DESEMPENHO E TÉCNICAS
CLÁSSICAS DE OTIMIZAÇÃO DE PROGRAMAS ...... 35
3.1 - Introdução .................................................................................................. 35
3.2 - Análise de Desempenho ............................................................................ 35
3.3 - Otimização e Arquitetura .......................................................................... 36
CAPÍTULO 4 - METODOLOGIA PARA PARALELIZAÇÃO DE PROGRAMAS CIENTÍFICOS ............................................ 39
4.1 - Introdução ............................................................................................... 39
4.2 - Comparação com as Metodologias Clássicas de Paralelização .............. 39
4.3 - Organização da Metodologia .................................................................. 40
4.3.1 - Pré-requisito ........................................................................................... 41
4.3.2 - Primeiro Passo: Preliminares .................................................................. 41
4.3.3 - Segundo Passo: Análise .......................................................................... 42
4.3.3.1 - Análise de Fluxo de Dados ..................................................................... 42
4.3.3.2 - Análise de Dependências ........................................................................ 43
4.3.4 - Terceiro Passo: Estratégia Geral de Paralelização .................................. 44
4.3.4.1 - Primeiro Nível – Vetorização ................................................................. 44
4.3.4.2 - Segundo Nível – Paralelização Implementada por Diretivas ................. 46
4.3.5 - Quarto Passo: Resultados ........................................................................ 52
4.3.5.1 - Análise dos Resultados Numéricos ......................................................... 52
4.3.5.2 - Análise de Desempenho .......................................................................... 53
4.3.5.3 - Programa Executável .............................................................................. 53
CAPÍTULO 5 - APLICAÇÃO DA METODOLOGIA EM UM
PROBLEMA REAL ............................................................. 55
5.1 - Introdução ............................................................................................... 55
5.2 - Características Computacionais do Modelo Eta ..................................... 56
5.3 - Primeiro Passo – Preliminares ................................................................ 56
5.3.1 - Elaboração da Árvore de Chamadas ...................................................... 56
5.3.2 - Medidas de Desempenho ........................................................................ 57
5.4 - Segundo Passo – Análise ........................................................................ 59
5.4.1 - Análise de Fluxo de Dados ..................................................................... 59
5.4.2 - Análise de Dependências ........................................................................ 60
5.5 - Terceiro Passo – Estratégia Geral de Paralelização ............................... 62
5.5.1 - Primeiro Nível – Vetorização ................................................................. 62
5.5.2 - Segundo Nível – Paralelização Implementada por Diretivas ................. 64
5.6 - Quarto Passo – Resultados ..................................................................... 69
5.6.1 - Análise dos Resultados Numéricos ........................................................ 69
5.6.2 - Análise de Desempenho ......................................................................... 73
5.6.2.1 - Primeiro Nível ........................................................................................ 73
5.6.2.2 - Segundo Nível ........................................................................................ 74
CAPÍTULO 6 - CONCLUSÕES .................................................................... 81
REFERÊNCIAS BIBLIOGRÁFICAS ............................................................... 85
APÊNDICE A - Descrição do Modelo Regional de Previsão de Tempo – Eta 89
APÊNDICE B - Descrição da Arquitetura das Máquinas NEC SX-4/SX-6 .....
93
LISTA DE FIGURAS
Pág.
2.1 - Arquitetura paralela de memória compartilhada 29
2.2 - Arquitetura paralela de memória distribuída 29
4.1 - Diagrama de medida de desempenho 41
4.2 - Explicitar o fluxo de dados 43
4.3 - Aplicação das técnicas de otimização clássicas 45
4.4 - Uso das técnicas de otimização e paralelismo implementado por diretivas 47
4.5 - Paralelismo implementado por diretivas (OpenMP) sobre a vetorização 47
4.6 - Procedimento puro 49
4.7 - Reestruturação de laço para paralelismo 51
4.8 - Estratégia de paralelização da metodologia 52
5.1 - Diagrama de chamadas do programa principal 57
5.2 - Estrutura do modelo Eta 59
5.3a - Paralelização do laço L 62
5.3b - Paralelização do laço J 62
5.4 - Tempo de processamento do código 64
5.5 - Árvore de chamadas do Módulo da Turbulência 66
5.6 - Árvore de chamadas do Módulo da Radiação 67
5.7 - Comparações do código vetorizado e não vetorizado 69
5.8 - Comparação do código vetorizado e paralelizado (8 processadores) 71
5.9 - Comparação de versões diferentes do compilador para o mesmo código 71
5.10 - Comparação de versões diferentes do código para o mesmo compilador 72
5.11 - Desempenho do modelo versão original versus versão com otimização vetorial
73
5.12 - Desempenho do código após primeiro passo da paralelização OpenMP 77
5.13 - Desempenho do Código paralelo OpenMP 77
5.14 - Medida de tempo por módulos 78
LISTA DE TABELAS
Pág.
5.1 - Procedimentos candidatos à vetorização 63
5.2 - Speedup da dinâmica com 2 processadores 75
5.3 - Speedup do módulo da Turbulência com 2 processadores 76
5.4 - Comparação entre as versões do Código 79
5.5 - Uso de memória 79
A1 - Grade horizontal Ε de Arakawa 89
A2 - Representação do esquema de degraus de montanhas e coordenada Eta (η) 91
B1 - Características da unidade vetorial do SX 93
B2 - Características da unidade superescalar do SX 94
B3 - Características da CPU do SX 95
B4 - Configuração do sistema multi-nó do SX-6 95
LISTA DE SIGLAS E ABREVIATURAS
BLAS - Basic Linear Algebra Subprograms
CPTEC - Centro de Previsão de Tempo e Estudos Climáticos
CPU - Central Processing Unit
INPE - Instituto Nacional de Pesquisas Espaciais
LAPACK - Linear Algebra PACKage
MIMD - Multiple Instruction stream, Multiple Data stream
MISD - Multiple Instruction stream, Single Data stream
MPI - Message Passing Interface
NAG - The Numerical Algorithms Group ltd.
NCEP - National Center for Environment Prediction
OSU - Oregon State University
PARIX - Parallel Extension to Unix
POSIX - Portable Operating System Interface
PVM - Parallel Virtual Machine
SIMD - Single Instruction stream, Multiple Data stream
SISD - Single Instruction stream, Single Data stream
TLB - Translation Lookaside Buffer
WSCAD - Workshop em Sistemas Computacionais de Alto Desempenho
23
CAPÍTULO 1
INTRODUÇÃO
Este trabalho propõe nova metodologia para paralelização de programas científicos para
máquinas de memória compartilhada. A metodologia permite paralelizar um programa
científico sem o conhecimento prévio da sua formulação matemática. Situa-se entre dois
métodos clássicos de paralelização - o que advém do conhecimento da formulação
matemática e o automático, gerado por compiladores paralelizadores.
O primeiro método indica direções do paralelismo através da compreensão da
formulação matemática, dos métodos numéricos empregados para solucionar as
equações e sua implementação no código. Partindo desse conhecimento, utiliza-se a
análise do código fonte para paralelizar o programa.
O segundo método simplesmente submete o código a um compilador paralelizador que
extrai, automaticamente, as oportunidades de paralelismo. Este segundo método não
requer qualquer conhecimento da formulação matemática do problema – baseia-se
inteiramente na análise de dependências do código fonte.
O novo método busca direções do paralelismo sem contemplar a formulação
matemática. A metodologia proposta utiliza fundamentalmente a informação de quais
direções são independentes nos processos. O estudo profundo da implementação do
código valida as direções (quando disponíveis) ou obtém as direções (quando
desconhecidas), permitindo a aplicação do paralelismo. Dessa forma, a intervenção
humana na análise de dependências ultrapassa os limites das implementações
automáticas, mesclando informações pré-existentes das direções possíveis de
paralelismo com as que advêm do estudo do código.
A metodologia foi aplicada a um modelo numérico de previsão do tempo – Modelo
Regional Eta – utilizando a máquina de arquitetura vetorial e paralela de memória
compartilhada NEC/SX4 e a máquina de arquitetura híbrida NEC-SX6, apesar da
metodologia não abranger máquinas de memória distribuída. A demonstração da
metodologia, suas vantagens e desvantagens, as dificuldades de se paralelizar numa
24
máquina que contempla dois níveis de paralelismo – vetorização e paralelização e os
resultados obtidos serão abrangidos no escopo deste trabalho.
1.1 Trabalhos Similares
Há diversos exemplos de aplicação do paralelismo no modelo Regional Eta, dentre eles
o National Center for Environment Prediction (NCEP) que paralelizou o modelo Eta
utilizando OpenMP e Message Passing Interface (MPI). Resulta desse esforço a versão
operacional atual do NCEP, executada em 400 processadores de um IBM RS/6000-SP,
com 60 níveis verticais, resolução horizontal de 12 Km em um domínio horizontal de
700 X 1000 pontos [3]. Outro exemplo de paralelização do Eta foi o The Weather
Forecasting System SKIRON [4], desenvolvido pelo grupo do Departamento de
Informática, seção de Informática Teórica da Universidade de Atenas em 1998. Esse
paralelismo utilliza o Parallel Virtual Machine (PVM), Message Passing Interface
(MPI) e Parallel Extension to UNIX (PARIX). Resultados foram obtidos em uma
máquina Parsytec CC-8 usando PVM e PARIX, e em uma máquina Convex Exemplar
SPP-1600 com 8 nós usando PVM e MPI.
Outro exemplo sobre a paralelização do modelo Eta, foi realizado pela autora e pode ser
visto nos anais do WSCAD 2003 (IV Workshop em Sistemas Computacionais de Alto
Desempenho) [12]. Este trabalho é a aplicação da metodologia proposta a um problema
real, utilizando inicialmente o NEC/SX4 e em seguida o NEC/SX6.
Entretanto, não é do conhecimento da autora qualquer outro trabalho que determine as
informações efetivamente necessárias para a paralelização, bem como limitar quais
dessas informações emanam da formulação matemática e quais emanam do estudo do
código.
1.2 Nomenclatura
Embora vetorização e paralelização de memória compartilhada constituam dois níveis
de paralelismo, utilizaremos o termo paralelismo para indicar o segundo desses níveis,
obtido pelo uso de diretivas OpenMP. O primeiro nível será denominado vetorização.
25
Do mesmo modo, embora o movimento da atmosfera ocorra por processos físicos como
os dinâmicos, turbulentos, convectivos e a radiação, será utilizada a nomenclatura usual
da meteorologia, que diferencia os processos da dinâmica dos demais processos, que
passam a ser denominados processos físicos. Desta forma, há duas classes de processos
no modelo Eta: os físicos (turbulência, convecção e radiação) e os dinâmicos.
1.3 Estrutura da Dissertação
O Capítulo 2 apresenta aspectos gerais de paralelismo, arquiteturas de máquinas
paralelas e suas peculiaridades. Embora este trabalho utilize apenas conceitos de
arquiteturas de memória compartilhada, os demais conceitos estão colocados por
completude.
O Capítulo 3 apresenta de forma sucinta os conceitos e ferramentas para a análise e
otimização de códigos seqüenciais. Dentre as inúmeras técnicas clássicas de otimização
de códigos, detalham-se as duas técnicas mais utilizadas na paralelização do ETA.
O Capítulo 4 apresenta os passos da metodologia, os requisitos básicos, as
reestruturações de software que são passos preliminares da metodologia e a estratégia de
paralelização.
O Capítulo 5 apresenta a aplicação da metodologia a um problema real, o histórico de
desenvolvimento da vetorização e da paralelização e os resultados atingidos.
O Capítulo 6 contém as conclusões e trabalhos futuros.
26
27
CAPÍTULO 2
PROCESSAMENTO PARALELO
2.1 Introdução
Neste trabalho, define-se processamento paralelo como o uso simultâneo de múltiplos
processadores para reduzir o tempo de execução de um programa. Nota-se que há outras
formas de paralelismo que não são tratadas neste trabalho: paralelismo ao nível de bits
(na implementação de uma instrução) e paralelismo ao nível de instrução (múltiplas
instruções de um mesmo fluxo sendo executadas simultaneamente, como em uma
máquina super escalar). O enfoque desse trabalho é apenas em paralelismo ao nível de
processos.
Essa forma de processamento paralelo requer máquinas com múltiplos processadores,
sistemas operacionais capazes de suportar e de gerenciar esses processadores e
aplicações que explorem essa forma de paralelismo.
Este Capítulo apresenta conceitos básicos dessa forma de processamento paralelo:
arquitetura de computadores paralelos, modelos de programação paralela e padrões de
programação paralela.
2.2 Arquiteturas de Máquinas Paralelas
Segundo a taxonomia de Flynn [5] as arquiteturas paralelas são do tipo SISD (single
instruction stream, single data stream) como em uniprocessadores, SIMD (single
instruction, multiple data) onde a mesma instrução é executada por múltiplos
processadores em dados distintos, MISD (multiple instructrion stream, single data
stream) onde múltiplas instruções operam simultaneamente sobre o mesmo fluxo de
dados e MIMD (multiple-instruction stream multiple-data stream) onde cada
processador executa suas instruções no seu conjunto de dados.
28
As máquinas MIMD são classificadas em duas categorias: memória compartilhada e
memória distribuída [6], em função da memória endereçável por cada processador. Em
máquinas de memória compartilhada, todos os processadores endereçam toda a
memória. Em máquinas de memória distribuída, cada processador endereça apenas um
trecho da memória total.
Uma classificação importante para o entendimento e utilização de arquiteturas paralelas
é quanto ao tipo de paralelização homogênea e heterogênea e o conceito de
granularidade [7]. Sucintamente, a paralelização homogênea é a execução paralela do
mesmo código sobre múltiplos dados. A paralelização heterogênea é a execução de
códigos múltiplos sobre dados múltiplos. Geralmente utilizada quando é possível a
decomposição de tarefas a serem executadas em paralelo. A granularidade é uma
medida da quantidade de processamento envolvido em uma subtarefa, ela pode ser fina
ou grossa. Se uma subtarefa faz uma única atribuição ao dado pode ser considerada
como granularidade fina. Se envolver execução de múltiplas atribuições ou mesmo
chamadas de subrotinas pode ser considerada de granularidade grossa. Considerando os
tipos de paralelização citadas e a combinação com o fator granularidade é possível
determinar alguns paradigmas de programação paralela [7].
2.2.1 Arquiteturas de Memória Compartilhada
Máquinas de memória compartilhada possuem uma memória global acessível por todos
os processadores. A forma simples de sua configuração é mostrada na Figura 2.1. Cada
processador possui alguma memória local tal como registradores e/ou memória
cache[8]. Um exemplo dessa arquitetura é o NEC/SX4 do CPTEC/INPE composto por
8 processadores. É uma máquina de processamento vetorial e paralelo, onde cada
processador possui unidade vetorial e escalar. O início deste trabalho foi realizado nesta
máquina e foram criados dois níveis de paralelismo – vetorial e paralelo implementado
por diretivas para uma aplicação de modelagem regional de tempo. O mesmo sistema
operacional controla todos os processadores.
29
CPUCPU CPU CPU
Memória principal
FIGURA 2.1 – Arquitetura paralela de memória compartilhada.
Os processadores operam de maneira independente, porém apenas um processador por
vez pode acessar cada endereço da memória compartilhada. A principal característica de
sistemas de memória compartilhada é que o tempo de acesso à memória é independente
do processador solicitando a memória. Isso não elimina a disputa por acessos a
memória. Casos como falhas de acesso e conflito em bancos de memória afetam o
desempenho tal como em um sistema uniprocessado [9].
A vantagem desta arquitetura é a facilidade no uso e a rapidez na transferência de dados
entre processadores. Entretanto o número de processadores é limitado pela
complexidade do sistema de acesso simultâneo à memória. Essa é a principal limitação
dessa arquitetura: a baixa escalabilidade.
2.2.2 Arquiteturas de Memória Distribuída
Máquinas de memória distribuída não compartilham memória – cada processador
possui sua própria memória, invisível a todos os outros processadores. Processadores
são interconectados por uma rede de comunicação como mostra a Figura 2.2.
FIGURA 2.2 – Arquitetura paralela de memória distribuída.
CPU
Memória
CPU
Memória
CPU
Memória
CPU
Memória
CPU
Memória
CPU
Memória
Rede de interconexão
30
Os processos de uma aplicação paralela utilizam troca de mensagens para obter ou
alterar os dados nas memórias dos outros processos. A vantagem dessa arquitetura é sua
escalabilidade, maior que em máquinas com memória compartilhada, exatamente por
não possuir acesso simultâneo à memória. Além disso, cada processador acessa sem
interferência sua memória local. A desvantagem é o elevado overhead de comunicação
entre os processadores. Em geral, a rede de comunicação possibilita uma alta taxa de
comunicação e os processadores podem ser utilizados como computadores individuais.
Cada processador possui seu próprio sistema operacional.
2.2.3 Arquiteturas Híbridas
Dentre as diversas formas possíveis de misturar as duas arquiteturas (memória
compartilhada e memória distribuída), destacamos a arquitetura conhecida como
Cluster.
Trata-se de um conjunto de n nós de processamento, cada nó formado por p
processadores. Cada nó é uma máquina de memória compartilhada. Os múltiplos nós
formam uma máquina de memória distribuída. Em casos extremos, clusters degeneram
em arquitetura de memória compartilhada (quando n=1), em arquitetura de memória
distribuída (quando p=1) ou em uni-processadores (quando n=p=1). Um exemplo dessa
arquitetura é o NEC/SX6 do CPTEC/INPE que possui 4 nós com 8 processadores. É
também uma máquina de processamento vetorial e paralelo, onde cada processador
possui unidade vetorial e escalar. A conclusão deste trabalho foi realizada nessa
máquina; entretanto não foi aplicado o terceiro nível de paralelismo que seria o
paralelismo por troca de mensagens.
2.3 Modelos de Programação Paralela
Modelos de programação paralela utilizam o conceito de processos. Um processo é um
programa em execução, uma abstração que reúne atributos como espaço de
endereçamento, estruturas de dados, permissões de acessos, quotas, etc. O paralelismo é
obtido pela execução simultânea de um conjunto de processos que resolve um problema
31
único. A redução do tempo é efetiva se os processos executarem simultaneamente em
processadores distintos.
A eficácia do paralelismo depende de como a computação seqüencial é dividida entre os
processos que compõe o programa paralelo. Essa divisão é conhecida como partição do
problema.
As principais formas de particionar problemas são a partição de domínio e a partição de
tarefas. Na partição de domínio, os dados do problema são divididos entre os processos.
Na partição de tarefas, as tarefas que compõe a solução do problema são divididas entre
os processos. Ou seja, na partição de domínio cada processo executa a mesma
computação em parte do conjunto de dados, enquanto na partição de tarefas cada
processo executa uma tarefa sobre todos os dados.
A quantidade de trabalho que cada processo realiza é chamada de carga do processo e
distribuir a carga igualmente para todos os processos é denominado balanceamento de
carga. É um fator importante para garantir que a carga de trabalho seja bem distribuída
entre os processadores. Desta forma, a eficácia do paralelismo depende
fundamentalmente da partição do problema e do balanceamento de carga.
Os principais modelos de paralelismo são a troca de mensagens entre processos e o
modelo fork-join de processos.
2.3.1 Fork-join
Neste modelo, processos usam primitivas do sistema operacional para criar e destruir,
dinamicamente, outros processos. Esse modelo, originalmente criado para especificar
concorrência, foi introduzido por Connway (1963) e Dennis e Van Horn (1966). O uso
da função fork( ) cria dinamicamente cópia do processo que a invoca. Logo, o código do
novo processo (processo filho) é o mesmo do processo que o criou (processo pai).
Processos pais podem criar diversos processos filhos. A única diferença entre eles é o
número identificador do processo (PID); pais e filhos compartilham o mesmo espaço de
endereçamento.
32
A primitiva inversa de fork (que divide uma única computação em duas independentes),
é a primitiva join, que agrupa os processos concorrentes criados por fork. Invocada pelo
pai, a primitiva join suspende o processo pai até que o filho termine. Esse modelo de
programação requer paralelismo de memória compartilhada, pois pais e filhos dividem
o mesmo espaço de endereçamento. O modelo de programação permite flexibilidade
pelo fato dos processos serem criados dinamicamente; entretanto, a criação de
processos requer grande tempo de execução.
Para reduzir o tempo de criação, utilizam-se threads no lugar de processos. Thread é um
processo leve. Cada thread tem sua própria pilha, registradores e contador de
instruções; os demais elementos (espaço de endereçamento, ambiente, etc) são herdados
do processo que cria a thread. O sucesso desse conceito levou-o à padronização POSIX
(POSIX Standard 1003.1c, “System Application Program Interface, Amendment 2:
Threads Extension”).
2.3.2 Troca de Mensagens
O modelo de programação por troca de mensagens trata de paralelismo de memória
distribuída. Nesse modelo, o compartilhamento dos dados é feito via troca de
mensagens entre os processos. São processos independentes e possuem espaço de
endereçamento próprio.
O compartilhamento dos dados entre os processos é executado por comandos
explicitados pelo programador. Se for explicitado que um processo envia dados para
outro, o processo que recebe os dados também deve explicitar a recepção. A
decomposição de domínio ou de tarefas entre os processadores também é feita de forma
explícita.
2.4 OpenMP
Para exemplificar o modelo de programação de memória compartilhada fork-join será
citado o padrão de fato OpenMP [1] que foi extensamente utilizado neste trabalho. É um
padrão de paralelismo explícito que usa diretivas de programação com interface para
33
linguagem C e Fortran. Os compiladores traduzem as diretivas para as primitivas do
sistema operacional baseadas em threads. Visto que essas diretivas são comentários na
linguagem de programação, o programa paralelizado utilizando OpenMP pode também
ser executado seqüencialmente se o compilador não for munido com OpenMP. Sua
aplicação é incremental e combina código serial e paralelo num mesmo programa.
Como se trata de um padrão de programação, a portabilidade de um programa
paralelizado por OpenMP é garantida.
A região paralela é a estrutura básica do paralelismo OpenMP e define uma seção do
programa paralelo. Inicia-se a execução com uma única thread (denominada thread
master) e quando uma região paralela é encontrada, automaticamente a thread master
cria um conjunto de threads que executarão concorrentemente. Portanto é
imprescindível minimizar o número de regiões paralelas abertas para reduzir o overhead
de criação e destruição de threads. Dentro de uma região paralela, as variáveis podem
ser privadas ou compartilhadas. Todas as threads vêem a mesma cópia das variáveis
compartilhadas e vêem a sua cópia das variáveis privadas, que não são visíveis pelas
outras threads.
Sua utilização é fácil e trata mais freqüentemente de paralelismo de dados em laços.
Cada conjunto de dados é processado concorrentemente entre os processadores até o
término das execuções de cada conjunto (construção work-sharing). A sincronização
das threads é implícita pela existência de uma barreira implícita no término de cada
laço. Os processos aguardam o final da execução do último conjunto de dados para
continuar. O sincronismo pode se tornar explícito se o programador especificar o local
onde haverá ou não essas barreiras.
A distribuição do conjunto de dados para cada processador é feita também de forma
automática sendo possível modificar o schedule dos laços. Isso afetará somente o modo
como a iteração dos laços é mapeada sobre as threads, entretanto o balanceamento de
carga é implícito.
O uso de OpenMP gera programas paralelos somente para máquinas de memória
compartilhada. Entretanto a vantagem desse padrão de programação é que sua aplicação
34
é simples, portável e pode ser gradativamente aplicado, evitando extensa recodificação
do programa.
2.5 MPI
O padrão MPI [10] é uma biblioteca desenvolvida para ser padrão em ambientes de
memória distribuída usando troca de mensagens. O objetivo do MPI é simplesmente
estabelecer um padrão para programar usando troca de mensagens tornando o programa
mais portável, eficiente e flexível. O padrão fornece bibliotecas de rotinas padronizadas
para linguagens C e Fortran. Programas implementados com MPI somente podem ser
executados usando essas bibliotecas, mesmo utilizando apenas um processador. Todo o
paralelismo é explícito, o programador é o responsável em identificar o paralelismo e
implementar um algoritmo utilizando construções com o MPI. A decomposição de
domínios é explicitada pelo programador e cada processo é responsável pelo seu
conjunto de dados. Conseqüentemente o balanceamento de carga também é explícito. O
paralelismo não é construído em cima de um código seqüencial original como no
OpenMP, ele deve ser alterado para acomodar o paralelismo. Mensagens de envio e
recebimento tornam o sincronismo explícito. O uso de MPI gera programas paralelos
mais gerais por executarem em máquinas de memória compartilhada e distribuída, e são
suportados em diversos sistemas operacionais. Entretanto requer extensa recodificação
do programa.
Este trabalho não abrange máquinas de memória distribuída, pois a metodologia foi
desenvolvida para arquiteturas de memória compartilhada. O capítulo a seguir mostra
algumas técnicas de otimização de códigos seqüenciais que foram extensamente
utilizadas na aplicação da metodologia para um problema real.
35
CAPÍTULO 3
ANÁLISE DE DESEMPENHO E TÉCNICAS CLÁSSICAS
DE OTIMIZAÇÃO DE PROGRAMAS
3.1 Introdução
Este Capítulo apresenta, de forma sucinta, conceitos e ferramentas para a análise e
otimização de programas seqüenciais. O objetivo de otimizar um programa é reduzir seu
tempo de execução e conseqüentemente aproveitar de forma eficiente os recursos de um
processador. A otimização seqüencial deve preceder qualquer trabalho de paralelização,
pois um programa paralelo com baixo desempenho seqüencial apenas propaga a
ineficiência pelos processadores. Portanto é essencial que o programa seqüencial seja
aprimorado para utilizar eficientemente um processador antes da paralelização.
3.2 Análise de Desempenho
A análise de desempenho constitui o ponto de partida para a otimização e tem como
objetivo identificar os pontos críticos do programa ou partes do programa onde ocorre
afunilamento do fluxo de dados ou instruções e conseqüentemente consomem maior
tempo de processamento. Algumas técnicas de análise são utilizadas com o auxílio de
perfiladores [6] que amostram estatisticamente a execução do programa. Em intervalos
de tempo fixos, os perfiladores interrompem a execução do programa e coletam os
dados necessários. Perfiladores tem múltiplas funcionalidades, mas de forma geral é
possível fazer uma análise de desempenho com qualquer um deles. Exemplos de
perfiladores são: prof, gprof e tprof, disponíveis na maioria dos sistemas operacionais
UNIX.
Para cronometragem de programas existem várias rotinas que podem ser do sistema ou
rotinas em linguagens como Fortran e C. Alguns exemplos são as funções time, timex
do sistema operacional e as rotinas gettimeofday em C, cpu_time e system_clock em
Fortran.
36
3.3 Otimização e Arquitetura
Como otimização significa utilização eficiente dos recursos disponíveis, trata-se de uma
adaptação do algoritmo às características da máquina. Antes de considerar as técnicas
de otimização [6], é conveniente considerar a hierarquia de memória com especial
atenção ao consumo de tempo na transferência de memória entre camadas dessa
hierarquia. Um programa otimizado busca maximizar os acessos às memórias cache [8]
e minimizar os travamentos nos pipelines [8] da CPU. O programa deve ser ajustado
para diminuir os erros de acessos à memória cache de dados, de instrução e de TLB
(translation lookaside buffer) [8]. Uma boa utilização da memória significa minimizar
as transferências dos dados, processando antes que ocorram as falhas de localização.
Visa explorar a localidade espacial e temporal dos dados acessando posições contíguas
da memória. A transferência de uma linha de cache de cada vez, favorece que as
operações temporalmente próximas explorem os endereços adjacentes. Normalmente o
fluxo de dados é o fator crítico, raramente o volume de instruções é crítico no uso de
memória.
O uso das técnicas de otimização clássicas soluciona alguns desses casos críticos e
permite melhorar o desempenho dos programas. Algumas técnicas de otimização são
classificadas a seguir como:
- Otimizações aritméticas – uso de bibliotecas de subrotinas destinadas a
operações matemáticas. As bibliotecas mais populares possuem versões
otimizadas para cada máquina alvo. Algumas bibliotecas de subrotinas
numéricas são a BLAS, LAPACK, NAG.
- Otimizações de laços – laços normalmente gastam bastante tempo de
processamento em programas numericamente intensivos. Por esse motivo, a
organização dos laços em um aninhamentos de laços de forma a minimizar
transferências de memória é fundamental quando se busca o desempenho. É
importante considerar a arquitetura e a linguagem de programação para
explorar os acessos a posições contíguas de memória. Como o armazenamento
dos elementos de um array em Fortran é feito por colunas, explorar a
37
localidade espacial em Fortran significa reservar o laço mais interno de um
aninhamento de laços para percorrer as colunas do array.
Dentre as várias técnicas de otimização existentes, duas serão exemplificadas em
detalhe, pois foram extensamente utilizadas neste trabalho.
- Fusão de laços: alguns laços adjacentes podem ser fundidos em um único laço
para reduzir o overhead do laço e o tráfego de memória, melhorando o
desempenho. No exemplo abaixo, a economia advém das eliminações do
segundo laço e da recarga do array A.
!Fragmento não otimizado DO i = 1,1000 X=X*A(i)+B(i) END DO DO i=1,1000 Y=Y*A(i)+C(i) END DO
!Fragmento otimizado DO i = 1,1000 X=X*A(i)+B(i) Y=Y*A(i)+C(i) END DO
- Inversão de laços: essa técnica reorganiza os laços trocando-os de posição em
aninhamento de laços. Por exemplo, invertendo os dois laços do fragmento de
programa a esquerda produz o fragmento de programa a direita.
!Fragmento não otimizado DO i = 1, 100 DO j = 1, 100 A[i,j] = A[i, j] + K END DO END DO
!Fragmento otimizado DO j = 1, 100 DO i = 1, 100 A[i,j] = A[i, j] + K END DO END DO
A vantagem da inversão de laços é que pode reduzir os passos de acesso (stride) aos
elementos do vetor e usar de forma mais eficiente o cache. Essa técnica também pode
permitir que o laço mais interno, que acessa posições contíguas de memória, seja
vetorizado e o laço mais externo seja paralelizado.
Outras técnicas permitem economia de ciclos, como por exemplo reduzir ao mínimo o
número de chamada a subrotinas. Quando subrotinas pequenas são invocadas múltiplas
38
vezes, o texto da subrotina pode ser inserido no programa que a invoca, eliminando a
chamada. Essa técnica conhecida como inlining geralmente é bastante eficiente.
Uma técnica de otimização eficiente para máquinas vetoriais quando tratamos laços
muito extensos é a quebra de laços. Muitas vezes laços extensos podem não ser
vetorizados por apresentarem partes do corpo do laço não vetorizáveis. Quando
quebrados em laços menores a otimização pode ocorrer utilizando algumas das técnicas
ou combinações de técnicas citadas.
Ainda se tratando de máquinas vetoriais, é imprescindível prever as direções de
vetorização e paralelização, de forma que o ganho de paralelismo não seja à custa de
perdas de vetorização. Neste caso, é recomendável um estudo durante a otimização
seqüencial, evitando o conflito durante a paralelização.
Após o programa ser otimizado seqüencialmente é necessário examinar a validade das
otimizações. Os resultados numéricos devem manter-se inalterados, exceto por
eventuais diferenças de arredondamento.
O próximo Capítulo trata da metodologia aplicada a programas científicos, partindo da
otimização seqüencial até a paralelização para computadores de memória
compartilhada.
39
CAPÍTULO 4
METODOLOGIA PARA PARALELIZAÇÃO
DE PROGRAMAS CIENTÍFICOS
4.1 Introdução
A metodologia proposta para paralelização de programas científicos visa máquinas
paralelas de memória compartilhada e paralelismo por partição de domínios. Esta
metodologia está situada entre as duas metodologias clássicas – a tradicional, que busca
a direção do paralelismo através da formulação matemática e dos métodos numéricos
utilizados e a automática, que busca direções do paralelismo restritos à análise de
dependências nos laços. A metodologia proposta busca as direções possíveis de
paralelismo através de informações superficiais da modelagem e essencialmente da
implementação do programa. Essas informações visam determinar em quais direções
existem dependências. É um complemento ao método automático do compilador, que
não percebe algumas direções de paralelismo por conseqüência da implementação do
programa. As técnicas e os mecanismos necessários para prover o paralelismo serão
descritos na organização da metodologia.
4.2 Comparação com as Metodologias Clássicas de Paralelização
A metodologia tradicional para paralelizar um programa pré-existente é composta pelos
seguintes passos:
a) Compreender sua formulação matemática;
b) Determinar direções de independências;
c) Entender os métodos numéricos empregados;
d) Encontrar no programa a implementação dos métodos numéricos;
e) Paralelizar utilizando as informações obtidas nos passos anteriores.
40
A vantagem dessa metodologia é o domínio do programa adquirido do equacionamento
matemático e do conhecimento dos métodos numéricos utilizados. A desvantagem é o
tempo gasto no entendimento das equações e dos métodos numéricos, aliado a não
garantia de paralelização.
A outra metodologia clássica é a automática, que simplesmente submete o programa a
um compilador paralelizador, que extrai as oportunidades de paralelismo pela análise de
dependências dos laços. O único passo dessa metodologia é compilar utilizando uma
chave de compilação que insira diretivas de paralelização no programa.
É interessante observar que essa última metodologia não tem qualquer conhecimento da
formulação matemática do problema. A vantagem é que o trabalho de análise é feito
pelo compilador. As desvantagens são a ineficiência do método (obtém pouco
paralelismo) e, em alguns casos, incorreções no processo (produz código errado).
A metodologia proposta utiliza fundamentalmente a informação das direções
independentes para obter paralelismo e estudo profundo da implementação do
programa. A partir daí, a intervenção humana na análise de dependências ultrapassa os
limites das implementações automáticas.
4.3 Organização da Metodologia
A primeira fase da paralelização é buscar a compreensão superficial do problema. Em
seguida, entender a estrutura do programa é uma forma de integrar-se com o programa e
obter meios de reestruturá-lo. Nessa etapa é importante prever tanto as otimizações
seqüenciais quanto o paralelismo. Para explorar paralelismo de dados em memória
compartilhada, basta paralelizar ninhos de laços através de diretivas inseridas no
programa. Mas é importante que o paralelismo seja estrategicamente aplicado para ser
eficiente, por isso paralelizar os laços mais externos é mandatório.
A metodologia proposta é aplicada a programas científicos para máquinas de memória
compartilhada, por esse motivo o paralelismo que é implementado por diretivas será
demonstrado com o padrão OpenMP. Como a linguagem científica de programação
mais comum é o Fortran, os exemplos citarão esta linguagem. Mas a metodologia
41
também se aplica a outras linguagens de programação, respeitadas suas construções
características.
4.3.1 Pré-requisito
a) Conhecimento da arquitetura alvo;
b) Domínio das técnicas de otimização de programas;
c) Conhecimento superficial do problema: do que se trata e como funciona.
4.3.2 Primeiro Passo – Preliminares
a) Elaborar a árvore de chamadas;
b) Medidas de desempenho
As medidas de desempenho são requisitos necessários para aumentar a eficiência da
otimização. Para auxiliar o trabalho de análise, é fundamental utilizar ferramentas para
medir o tempo gasto pelos procedimentos, ordenando os procedimentos em ordem
decrescente do tempo de execução. Ferramentas próprias para a análise são os
perfiladores e a instrumentação manual, já tratadas no Capítulo 3. A Figura 4.1 mostra
um exemplo de programa em Fortran 90 instrumentado com a função system clock.
PROGRAM main CALL SYSTEM_CLOCK (ti,c_rate) DO ... CALL SYSTEM_CLOCK (t1) CALL subroutine_1 CALL SYSTEM_CLOCK (t2) ... CALL SYSTEM_CLOCK (t3) CALL subroutine_2 CALL SYSTEM_CLOCK (t4) ... t_sub1=t_sub1+ real(t2-t1)/real(c_rate) t_sub2=t_sub2+ real(t4-t3)/real(c_rate) END DO CALL SYSTEM_CLOCK (TF) END PROGRAM main
FIGURA 4.1 – Diagrama de medida de desempenho.
42
Os dados coletados tanto pela instrumentação automática quanto pela manual, ou pelo
uso das duas, indicarão direções propícias à otimização. Aliando-se o tempo decrescente
de processamento à menor complexidade do procedimento é possível definir os passos
do trabalho.
4.3.3 Segundo Passo – Análise
4.3.3.1 Análise de Fluxo de Dados
O objetivo desse passo é aumentar a legibilidade do programa e explicitar o fluxo de
dados entre os procedimentos. Nesta fase são eliminadas construções que impedem o
paralelismo, comuns em linguagem de programação não estruturada, e são eliminadas
referências à mesma área de memória. As variáveis globais e os argumentos formais de
procedimentos são identificados, incluindo sua intenção: de entrada, de saída ou de
entrada/saída. Desta forma possibilita-se clareza no fluxo de dados, portanto um ponto
de partida para entendimento do programa.
Um exemplo para esse passo da metodologia é a conversão de programas codificados
em Fortran 77 para Fortran 90. Aumentar a legibilidade do programa é mais simples em
Fortran 90 que em Fortran 77. Na conversão, o uso do implicit none obriga a declaração
de todas as variáveis facilitando sua identificação no programa. Ainda no processo de
conversão, é imprescindível eliminar equivalence e substituir go to por estruturas de
controle clássicas. Num segundo passo, explicitar o fluxo de dados inicia-se
substituindo os commons por modules. Todas as referências a commons são substituídas
por USE ONLY. Essa prática de programação permite enumerar apenas as variáveis
efetivamente utilizadas pelo procedimento. Simultaneamente, declara-se a intenção das
variáveis globais a cada procedimento, através de comentários afixados após cada
variável global da cláusula ONLY do USE. Em seguida identificam-se os argumentos de
cada procedimento através do uso do intent (in, out ou inout). A Figura 4.2 demonstra o
passo que explicita o fluxo de dados.
43
SUBROUTINE example (x,y,z,k)
! global variables
USE module_ex, ONLY: var1,var2,var3 !var1:intent(in)
!var2:intent(out)
!var3:intent(inout)
IMPLICIT NONE
! argument variables
REAL,DIMENSION(10),INTENT(IN) :: x
REAL,DIMENSION(20),INTENT(OUT) :: y
REAL,INTENT(INOUT) :: z
INTEGER,INTENT(IN) :: k
! local variables
INTEGER,DIMENSION(40) :: lv
...
END SUBROUTINE example
FIGURA 4.2 – Explicitar o fluxo de dados.
Como resultado, para conhecer o volume de dados e entender o fluxo de entrada e saída
de dados de cada procedimento, basta observar as declarações dos argumentos e o
comentário das variáveis globais. É um processo custoso, entretanto indispensável para
facilitar a análise do fluxo de dados.
Após essa fase de modificações, o programa está preparado para análise de dependência
de dados.
4.3.3.2 Análise de Dependências
A princípio, a análise de dependências deve ser feita de forma global antes de descer ao
nível dos laços. Isso não envolve o conhecimento matemático profundo das equações,
mas sim o conhecimento da(s) direção(s) independente(s) dos processos e a ordem em
que são calculados. Esse conhecimento pode ser obtido do texto do programa ou de
discussões com especialistas, entretanto é primordial a verificação e a validação das
independências na implementação do programa. Quando a informação prévia das
direções independentes não existir ou a implementação do programa não permitir a
44
paralelização, a análise de dependências pode tornar viável a identificação dessas
direções e auxiliar na reestruturação para obter o paralelismo.
Na análise de dependências devem ser considerados os conflitos de desempenho,
passíveis de ocorrência quando existem dois níveis de paralelismo a serem tratados – o
paralelismo implementado por diretivas e a vetorização. Muitas vezes ganhos em
paralelismo causam perdas vetoriais. Essencialmente esse é o ponto de partida para a
paralelização
4.3.4 Terceiro Passo – Estratégia Geral de Paralelização
A metodologia aplica a programação paralela explícita através de diretivas do
compilador. O paralelismo é efetuado por partição de domínio, ou seja, implica a
paralelização do mesmo programa sobre elementos múltiplos de dados. A paralelização
deve ser homogênea, e o principal aspecto é garantir que iterações de laços não
carreguem dependências. O procedimento para paralelizar um laço é converter cada
iteração ou bloco de iterações em um processo paralelo e executar esses processos
sincronizadamente. A paralelização é válida se não alterar o resultado do programa por
algum ciclo de dependência. O paralelismo explícito é uma forma do programador
controlar as porções do programa que serão paralelizadas e garantir as independências.
A estratégia geral de paralelização considera os dois níveis de paralelização possíveis
para máquinas de memória compartilhada – vetorização e paralelismo implementado
por diretivas.
4.3.4.1 Primeiro Nível – Vetorização
A vetorização é entendida como o primeiro nível de paralelismo devido ao uso dos
pipelines. É chamada de execução paralela por hardware. A primeira etapa da
paralelização visa aumentar o grau da vetorização. Os compiladores otimizantes para
máquinas vetoriais automatizam a tarefa de vetorização, embora sua eficácia seja
limitada pela implementação do programa. A intervenção humana facilitará o processo
de otimização seqüencial, ampliando a capacidade do compilador e aumentando o grau
de vetorização.
45
Nesta etapa, o uso das técnicas clássicas de otimização transforma laços seqüenciais em
laços paralelos. Técnicas principais:
(a) inversão de laços para permitir a vetorização na maior dimensão do vetor;
(b) quebra de grandes laços seqüenciais em laços menores para permitir a
vetorização;
(c) fusão de laços;
(d) reestruturação de laços seqüenciais [2] que gera aninhamentos de laços
vetorizáveis e paralelizáveis.
Ganhos notáveis ocorrem quando é possível combinar algumas técnicas de otimização.
Um exemplo é quando grandes aninhamentos de laços pouco vetorizáveis sofrem
modificações no programa e são quebrados em aninhamentos de laços menores. A
Figura 4.3 exemplifica essa combinação de técnicas. Analisando o código à esquerda,
um laço externo não é vetorizado pelo critério de dependência em i e j, outro fator é o
tamanho do laço vetorizado, que pela dimensão do problema, a variável l não ultrapassa
38 elementos, considerado curto.
+-->DO n=1,khshal | i=ishal(n) | j=jshal(n) |... |V-> DO l=ltp1,lbtk || ds(l)=(tr(i,j,l)-k(i,j,l) |V-> END DO |... |V-> DO l=ltp1,lbtk || IF( ... )THEN || go to 800 || ENDIF |V-> END DO |... | 800 CONTINUE +-->END DO
P-->DO l=1,lm |+-> DO j=1,jm ||V-> DO i=1,im ||| IF(mask(i,j)) ||| ds(i,j,l)=tr(i,j,l)- k(i,j,l) ||V-> END DO |+-- END DO P-->END DO ... P-->DO l=1,lm |W-> DO j=1,jm ||*-> DO i=1,im ||| IF(...) THEN ||| ENDIF ||*- END DO |W-- END DO P-->END DO
FIGURA 4.3 – Aplicação das técnicas de otimização clássicas.
Assim a transformação do laço, no código à direita, é necessária para eliminar as
dependências havendo uma reestruturação, quebra, inversão e fusão dos laços.
→ Vetor curto
→ Vetor longo
Quebra do laço →
→ Vetor super longo
→ Laço não vetori-zado
46
Conseqüentemente o laço curto passa a ser o laço mais externo e pode ser paralelizado,
permitiu-se a vetorização do laço longo i (em torno de 119 elementos) e no
aninhamento seguinte a quebra dos laços permitiu-se a fusão dos laços i e j tornando-se
o vetor super longo.
É importante que nessa etapa seja prevista a paralelização de segundo nível, para
facilitar o trabalho de aplicação e para evitar conflitos com a vetorização.
4.3.4.2 Segundo Nível – Paralelização Implementada por Diretivas
A segunda etapa da paralelização visa memória compartilhada. Para tanto, utiliza-se
uma estratégia de três passos:
a) Primeiro passo – paralelização de granulação fina
O objetivo desse passo é definir o laço que será paralelizado e o que será vetorizado. O
paralelismo é aplicado diretamente nos laços. Esse passo trata de trechos de programa
ou procedimentos que não invocam outros procedimentos.
É prioritário paralelizar o laço mais externo possível, quando há aninhamentos de laços
e vetorizar o laço mais interno e que seja na maior dimensão do vetor. Portanto,
combinar técnicas de otimização e paralelismo é o objetivo desse passo. A
demonstração de uma forma de otimizar um trecho de programa e aplicar paralelismo
numa quantidade maior de dados possíveis está representada na Figura 4.4.
Esse passo está restrito a laços com pouca complexidade de implementação, embora
percorra completamente o nível mais externo do programa. Apesar de estender esse
passo por todo o programa, os resultados de eficiência esperados são modestos,
exatamente por tratar de laços com pouca complexidade.
47
SUBROUTINE example1 ... ! preparatory calculations ... ! Calculate !$omp parallel DO l=2,lm wfix=0.9814*EXP(0.018*l) !$omp do DO n=1,npre uk(n)=u(n)*ul(l+(lm-lmh(n))) w(n)=0.1*(0.2*(tt(n)*wfix) END DO !$omp do DO n=1,npre ww(n)=cp(n)*(ht(n)*2) pr(n)=pr(n)*(ht(n)*2) psl(n)=psl(n)*(ht(n)*2) END DO !omp do DO n=1,npre IF(pid(n) == 1.)THEN ww(n)= dr(n)*(ht(n)*2) END IF END DO END DO ! end loop L !$omp end parallel END SUBROUTINE example1
SUBROUTINE example2 ... ! preparatory calculations ... ! Calculate !$omp parallel DO l=2,lm wfix=0.9814*EXP(0.018*l) !$omp do DO n=1,npre uk(n)=u(n)*ul(l+(lm-lmh(n))) w(n)=0.1*(0.2*(tt(n)*wfix) !loop fusion ww(n)=cp(n)*(ht(n)*2) pr(n)=pr(n)*(ht(n)*2) psl(n)=psl(n)*(ht(n)*2) END DO !omp do DO n=1,npre IF(pid(n) == 1.)THEN ww(n)= dr(n)*(ht(n)*2) END IF END DO END DO ! end loop L !$omp end parallel END SUBROUTINE example2
FIGURA 4.4 – Uso das técnicas de otimização e paralelismo implementado por
diretivas .
Nos casos onde a vetorização atinge o laço intermediário de um aninhamento, que
também é alvo de paralelismo, aplicar simplesmente a diretiva de paralelização pode
gerar ineficiência, como mostra a Figura 4.5. A solução é alterar o schedule desse laço,
dividindo-o em blocos que acessam posições contíguas de memória.
Vetorização em i e j Vetorização em i e Paralelização em j
Vetorização em i e Paralelização em j
+->DO l=1,lm |v->DO j=3,jm-2 ||v->DO i=1,im ||| ... ||v->END DO |v->END DO +->END DO
!$omp parallel +->DO l=1,lm | !$omp do |P-->DO j=3,jm-2 ||v-> DO i=1,im ||| ... ||v-> END DO |P-->END DO +->END DO !$omp end parallel
!$omp parallel +->DO l=1,lm | !$omp do & | !$omp schedule(static,jm-4/np) |P--->DO j=3,jm-2 ||v---> DO i=1,im ||| ... ||v---> END DO |P--->END DO +->END DO !$omp end parallel
Automática Distribuição cíclica (ineficiente)
Distribuição por blocos (eficiente)
FIGURA 4.5. Paralelismo implementado por diretivas (OpenMP) sobre a vetorização.
48
O resultado passa a ser satisfatório. De forma geral, os ganhos em paralelismo de
segundo nível não devem ser obtidos a custa da redução de operações vetoriais.
Outro fator importante é que quando se aplicar o primeiro passo a correção da
paralelização deve ser garantida por uma restrição – o programa paralelo deve produzir
o mesmo resultado que o programa seqüencial (exceto por diferenças de
arredondamento), para qualquer número de processadores.
b) Segundo passo – paralelização de granulação grossa
É paralelizar um trecho do programa ou procedimento que invoca outros
procedimentos. Tipicamente ocorre ao paralelizar laços que percorrem arrays de dados,
invocando um procedimento para cada elemento (ou seção) do array.
Este segundo passo, mais complexo que o anterior, exige grande esforço de
implementação, visto que é necessário garantir que iterações distintas do laço possam
ser executadas simultaneamente sem alterar o resultado da computação. Isto requer
transformar os procedimentos em procedimentos puros [11]. Entretanto, o ganho
computacional esperado é significativo.
Transformar um procedimento qualquer em um procedimento puro significa assegurar
que a execução do procedimento não produz nenhum efeito colateral. Numa função
pura, o único efeito de sua execução é retornar o resultado da função sem modificar os
valores de seus argumentos ou dados globais e sem executar I/O.
Uma subrotina pura também não deve produzir nenhum efeito colateral, o único efeito é
modificar os valores e/ou associação de ponteiros, de argumentos INTENT(OUT) ou
INTENT(INOUT). Variáveis globais (common) só serão usadas se forem INTENT(IN)
e não sofrerem nenhuma das restrições que serão descritas. A Figura 4.6 mostra a
construção de uma subrotina pura e uma função pura.
49
pure subroutine sub1(a) real,intent(in out) :: a ! intent must be declared interface pure function fun1(a) ! any invoked procedure must be pure real,intent(in) :: a end function fun1 end interface a=fun1(a/10.) end subroutine pure function fun1(a) real :: fun1 real,intent(in) :: a ! all arguments must be intent(in) fun1=a end function fun1
FIGURA 4.6 – Procedimento puro.
Algumas regras e restrições para procedimentos puros, conforme o padrão Fortran 90
[11], são descritas a seguir:
- Um argumento de uma função pura deve ser INTENT(IN), uma função ou um
ponteiro;
- Um argumento de uma subrotina deve ter seus INTENT especificados, exceto os
ponteiros ou retorno alternativo;
- Uma variável local de um procedimento puro não deve ter o atributo SAVE. As
variáveis locais também não podem ser inicializadas na definição da variável,
pois essas terão automaticamente o atributo SAVE;
- Todos os procedimentos internos a procedimentos puros devem ser puros;
- Um procedimento puro não deve conter atributo STOP, PRINT, OPEN, CLOSE,
BACKSPACE, ENDFILE, REWIND, INQUIRE e READ ou WRITE
especificando um arquivo externo;
- Em um procedimento puro qualquer variável que esteja em COMMON, ou
associada por USE ou HOST, ou seja INTENT(IN), ou armazenada em
associação com qualquer variável, não deve ser usada no seguinte contexto:
50
→ no lado esquerdo de uma atribuição de valores;
→ numa atribuição de ponteiro;
→ como um índice de comando DO;
→ como um item de entrada de um READ de um arquivo interno;
→ como um arquivo interno num WRITE;
→ como uma variável IOSTAT ou SIZE em um I/O de um arquivo interno;
→ como uma variável STAT ou objeto alocável de um ALLOCATE ou
DEALLOCATE;
→ como um objeto de ponteiro num NULLIFY;
Essas regras permitem que duas invocações ao procedimento possam ser executadas
concorrentemente. Quando não é possível paralelizar o laço que invoca um
procedimento ou uma árvore de procedimentos, a solução é descer um nível
imediatamente abaixo do procedimento e iniciar o trabalho de análise, voltando ao
primeiro passo da estratégia de paralelização.
Um fator importante quando se aplica paralelismo de dados é analisar a
reprodutibilidade binária. Para qualquer número de processadores utilizado, o resultado
numérico não deve ser alterado. Portanto qualquer que seja a alteração feita no
programa, desde o princípio, o programa deve ser testado com um a n processadores.
c) Terceiro passo – reestruturação de laços
Consiste em utilizar a técnica clássica de fusão de múltiplos aninhamentos de laços em
um único aninhamento, permitindo a paralelização de granulação grossa. Um exemplo
dessa combinação de técnicas está demonstrado na Figura 4.7.
51
O corpo do laço mais externo do aninhamento único é transformado em um
procedimento puro. O novo laço que percorre o número de processadores contém
apenas a invocação do procedimento.
Essa reestruturação particiona o domínio, sendo que cada porção do domínio é
executada num processo concorrente. Esse passo permite paralelizar o laço mais externo
podendo alcançar um expressivo ganho computacional.
SUBROUTINE example1 ... ! preparatory calculations ... ! Calculate !$omp parallel DO l=2,lm wfix=0.9814*EXP(0.018*l) !$omp do DO n=1,npre uk(n)=u(n)*ul(l+(lm-lmh(n))) w(n)=0.1*(0.2*(tt(n)*wfix) END DO !$omp do DO n=1,npre ww(n)=cp(n)*(ht(n)*2) pr(n)=pr(n)*(ht(n)*2) psl(n)=psl(n)*(ht(n)*2) END DO !omp do DO n=1,npre IF(pid(n) == 1.)THEN ww(n)= dr(n)*(ht(n)*2) END IF END DO END DO ! end loop L !$omp end parallel END SUBROUTINE example1
SUBROUTINE example3 ... ! preparatory calculations ... blk=ceiling(REAL(npnt)/ & REAL(nThreads)) DO n=1,nThreads ini(n)=blk*(n-1)+1 end(n)=MIN(blk*n,npnt) END DO ! Calculate sub !$omp parallel do DO n=1,nThreads CALL sub(ip,jp,ini(n),end(n)) END DO END SUBROUTINE example3 SUBROUTINE sub(ip,jp,ini(end(n)) ! Calculate DO l=2,lm wfix=0.9814*EXP(0.018*l) DO n=ini,end uk(n)=u(n)*ul(l+(lm-lmh(n))) w(n)=0.1*(0.2*(tt(n)*wfix) ww(n)=cp(n)*(ht(n)*2) pr(n)=pr(n)*(ht(n)*2) psl(n)=psl(n)*(ht(n)*2) END DO DO n=ini,end IF(pid(n) == 1.)THEN ww(n)= dr(n)*(ht(n)*2) END IF END DO END DO ! end loop L END SUBROUTINE sub
FIGURA 4.7 – Reestruturação de laço para paralelismo.
Esta metodologia ordena os passos em níveis crescentes de dificuldade e gera resultados
ao fim de cada passo.
A estratégia de paralelização de segundo nível da metodologia é aplicada de forma
cíclica, iniciando o trabalho pelo primeiro passo da estratégia. Em seguida o segundo
passo é aplicado, mas podendo retornar ao passo anterior. O terceiro passo se aplica
52
após percorrer o programa todo seguindo os passos 1 e 2.. Um diagrama desse passo da
metodologia é demonstrado na Figura 4.8.
FIGURA 4.8 – Estratégia de paralelização da metodologia.
4.3.5 – Quarto Passo – Resultados
4.3.5.1 Análise dos Resultados Numéricos
Os resultados numéricos não devem ser alterados exceto por diferenças de
arredondamento. Programas vetorizáveis mudam o resultado conforme a opção de
compilação empregada, devido ao uso de bibliotecas matemáticas distintas. Para o
paralelismo de segundo nível, é satisfatório que o resultado independa do número de
processadores.
Main
Laços chamam Proc.?
Sim Não
Passo 1
Passo 1
É possível Passo 3?
Não Sim
Passo 3
Exe
Passo 2
É possível paralelizar?
Não Desce 1 nível na arvore
Proc. Puro
Sim
53
Esses resultados podem ser avaliados por comparação da saída binária ou pelo
comportamento do fenômeno estudado. É importante que se adote um critério de
avaliação do resultado e segui-lo durante a aplicação da vetorização e paralelização.
4.3.5.2 Análise de Desempenho
Esse mecanismo é utilizado em todos os passos da estratégia de paralelização. Utiliza-se
a ferramenta de medidas de desempenho e avalia-se o ganho no trecho onde foi aplicado
aquele passo. Para a vetorização é importante avaliar o grau de vetorização do programa
e o tamanho médio dos vetores de trabalho. Para a paralelização utiliza-se a Lei de
Amdhal [6] para verificar o speedup e a eficiência do programa. Criar gráficos ao longo
do trabalho auxilia na análise de sua aplicação e também na verificação dos trechos ou
procedimentos que devem despender maior esforço.
Um fator importante quando se aplica o paralelismo de dados no programa é o razoável
balanceamento de carga esperado. A parte crítica do trabalho é construir um novo nível
de paralelismo (implementado por diretivas) sobre um nível previamente existente
(vetorização), sem que o novo nível elimine o anterior.
4.3.5.3 Programa Executável
Ao final do trabalho considerado satisfatório, um programa executável deve ser criado e
testado com um conjunto grande de casos. Essa avaliação deve ser feita para abranger o
maior número de condições possíveis dentro do programa, buscando a garantia de
funcionamento em todos os eventos.
O próximo capítulo trata da metodologia aplicada a um problema real, utilizando dois
níveis de paralelização – vetorização e paralelismo implementado por diretivas
OpenMP.
54
55
CAPÍTULO 5
APLICAÇÃO DA METODOLOGIA EM UM PROBLEMA REAL 5.1 Introdução
O desenvolvimento do processamento paralelo proporcionou aumento das aplicações
científicas computacionalmente intensivas e a necessidade de gerar programas
paralelos. Paralelizar programas científicos torna-se uma tarefa difícil quando se deseja
alcançar um bom desempenho. A proposta desta metodologia visa facilitar a adaptação
de programas seqüenciais em máquinas paralelas de memória compartilhada. Quando o
programa alvo não contempla, na sua concepção, a possibilidade de paralelização, é
necessário reestruturar o código para permitir o paralelismo. Em máquinas de
processamento vetorial e paralelo de memória compartilhada é necessário considerar
dois níveis de paralelismo – vetorização e paralelismo implementado por diretivas -
desta forma o trabalho de análise é primordial.
O programa utilizado trata o modelo regional de previsão de tempo – Eta que foi
desenvolvido na Universidade de Belgrado em cooperação com o Instituto de
Hidrometeorologia da Iugoslávia e o National Center for Environmental Prediction
(NCEP) em Washington [13][14]. Em meados de 1999 a versão operacional
(seqüencial) do NCEP foi instalada no Centro de Previsão de Tempo e Estudos
Climáticos (CPTEC) tornando-se em seguida operacional. O modelo operacional gera a
previsão diária de tempo para o território nacional.
Com a implantação operacional, houve a necessidade de modernização do código para
executar em vários processadores. A metodologia aplicada gerou uma nova versão do
código operacional, com modificações computacionais profundas para prover
paralelismo de dois níveis. No paralelismo implementado por diretivas foi utilizado o
padrão que resultou um código portátil com paralelismo também portátil para máquinas
de memória compartilhada.
56
5.2 Características Computacionais do Modelo ETA
Originalmente o código foi escrito em Fortran 77, com técnicas obsoletas de
programação. Apresentava uma estrutura inadequada para paralelismo e um baixo
desempenho vetorial. Os principais procedimentos não passavam os dados por
argumentos, atuavam sobre dados globais armazenados em 54 commons. O uso de
commons obrigava alocação estática de variáveis e dificultava a detecção das variáveis
de entrada e saída dos procedimentos. O entendimento dos fluxos de dados e de controle
do programa ainda era prejudicado pelo uso de equivalence e go to e as variáveis eram
declaradas implicitamente. Sintaticamente algumas palavras reservadas continham
espaços em branco que também dificultavam sua identificação no código.
As grandezas meteorológicas tri-dimensionais são implementadas por arrays indexados
por longitude(I), latitude(J) e nível vertical(L). De forma geral, a estrutura de laços tem
o seguinte formato:
DO L=1, lm → Camadas verticais DO J=1, jm → Pontos na latitude DO I=1, im → Pontos na longitude ... (bloco) END DO END DO END DO
Algumas estruturas de laços invocam procedimentos ou árvores de procedimentos e
algumas variações na ordem do aninhamento de laços são encontradas no decorrer do
código.
5.3 Primeiro Passo – Preliminares
5.3.1 Elaboração da Árvore de Chamadas
O primeiro passo da metodologia gerou a árvore de chamadas do modelo Eta. A
composição da árvore posiciona os procedimentos e detalha o fluxo de chamadas. A
versão original do código ETA é composta por 76 arquivos contendo procedimentos e
43 arquivos contendo includes files. O programa principal inicializa o modelo e
gerencia os procedimentos da dinâmica, da física e I/O através de um único laço
57
mostrado na Figura 5.1. Essa quantidade de arquivos dificulta o entendimento do
código, pois não é imediato determinar a função dos procedimentos contidos em cada
arquivo.
Programa Principal
CALL tree of initialization procedures
DO
! loop control
IF (ntsd .GE. ntstm) EXIT
ntsd = ntsd+1
CALL tree of dynamic procedures
CALL tree of physical procedures
CALL tree of I/O procedures
END DO
FIGURA 5.1 – Diagrama de chamadas do programa principal.
Seguindo a metodologia, o próximo passo é medir o desempenho do código e verificar a
ordem decrescente dos tempos de processamento.
5.3.2 Medidas de Desempenho
O procedimento adotado para análise de desempenho é identificar pontos críticos onde
o tempo de execução compromete o desempenho do programa. A ferramenta utilizada
para medir o tempo de processamento foi ftrace [15], uma ferramenta proprietária da
NEC para a análise detalhada de cada procedimento. O relatório produzido por essa
ferramenta apresenta os procedimentos em ordem decrescente de tempo de execução,
informando o tempo de execução acumulado no procedimento, o número de vezes que o
procedimento é invocado, a velocidade de processamento ponto-flutuante (em Mflops),
o grau de vetorização, o tamanho médio dos vetores, etc. Tal ferramenta foi
extensamente utilizada ao longo do trabalho, para priorizar procedimentos candidatos à
otimização e também para avaliar os resultados. Procedimentos foram escolhidos pela
58
combinação de alto tempo de execução com baixa complexidade da implementação.
Observe a seguir trecho do relatório produzido por ftrace na versão original do
programa, contendo os 13 primeiros procedimentos do relatório. Algumas informações
gerais que são importantes estão destacadas em negrito, como o número de Mflops, a
porcentagem de vetorização do código e o tamanho médio dos vetores.
*-------------------------------* SUMMARY LIST *-------------------------------* PERFORMANCE : 615.581 MOPS 215.195 MFLOPS (BY CPU TIME) VECTOR INFORMATION : VECTOR OPERATION RATIO = 92.93 % AVERAGE VECTOR LENGTH = 84.2 VECTOR REGISTER LENGTH = 256 *------------------------------------------------------* PROCEDURE SUMMARY LIST *------------------------------------------------------* PROCEDURE | FREQUENCY| EXCLUSIVE AV.TIME | MOPS MFLOPS| V.OP. AVER.| BANK | | TIME[SEC] (%) [MSEC] | | RATIO V.LEN| CONF sfcdif | 1372959| 81.450( 9) 0.059| 59.2 26.3| 0.00 73.4| cucnvc | 57| 72.430( 8) 1270.695| 784.6 243.5| 96.22 66.6| hzadv | 113| 58.952( 7) 521.701| 1227.7 431.4| 97.46 80.5| ttblex | 2223| 55.600( 6) 25.011| 107.0 28.2| 19.28 253.5| vdifh | 1372959| 52.785( 5) 0.038| 103.7 33.7| 43.44 34.0| chkout | 227| 46.119( 5) 203.168| 153.9 33.2| 60.22 106.8| turbl | 57| 43.760( 5) 767.720| 407.7 151.7| 93.08 65.0| vdifq | 1372959| 40.612( 4) 0.030| 142.1 56.5| 65.43 36.2| vdifv | 1372959| 38.465( 4) 0.028| 109.3 33.2| 36.22 33.6| pfdht | 227| 33.346( 3) 146.897| 2229.2 954.4| 98.91 110.1| prodq2 | 1372959| 30.438( 3) 0.022| 505.8 182.4| 95.11 28.9| radtn | 6| 29.833( 3) 4972.088| 171.5 42.9| 57.14 28.0| hzadv2 | 113| 27.318( 3) 241.751| 2099.1 476.8| 99.61 145.3|
Note o baixo desempenho vetorial (215 MFlops), quando comparado com a velocidade
de pico de um processador do NEC-SX4, onde foi iniciado o trabalho, que é 2Gflops.
Ou seja, atinge aproximadamente 10% da sua capacidade. A porcentagem do tempo de
execução escalar é 7,07% e os vetores de trabalho são pequenos (84 elementos, em
média), o tamanho médio é de 32,89% do tamanho ideal (256 elementos) de
aproveitamento dos pipelines [15]. O trabalho inicial foi uma extensa otimização
seqüencial para favorecer a paralelização de primeiro nível (vetorização), e em seguida
partir para a paralelização de segundo nível.
No caso do paralelismo implementado por diretivas (OpenMP), essa ferramenta fornece
volume excessivo de informações, pois reporta os parâmetros de execução acima
59
citados para cada região paralela de cada thread. Em primeira análise, é mais
conveniente instrumentar manualmente o código, medindo o tempo real de execução de
cada procedimento por meio de system clock (função intrínseca de Fortran 90). Um
exemplo da instrumentação do código pode ser visto no Capítulo 4.
Em segunda instância quando é necessário verificar se há overhead de chamadas as
bibliotecas de paralelismo, voltamos a utilizar ftrace.
5.4 Segundo Passo – Análise
5.4.1 Análise de Fluxo de Dados
Com o objetivo de aumentar a legibilidade e explicitar o fluxo de dados, o código foi
convertido para Fortran 90 e reestruturado em módulos. Esse processo foi executado em
três passos.
O primeiro passo converteu o programa para Fortran 90 declarando todas as variáveis,
eliminando equivalences e substituindo go to pelas estruturas de controle clássicas (If-
Then-Else).
O segundo passo substituiu os commons que eram referenciados por include ou
diretamente inseridos no código por modules. Procedimentos que referenciavam
variáveis em commons passaram a referenciá-las por Use only. Este mecanismo
explicita as variáveis globais que são efetivamente utilizadas no procedimento,
eliminando referências a variáveis globais não utilizadas.
O terceiro passo identificou a intenção dos argumentos dos procedimentos, usando a
declaração explícita (intent) de entrada, saída ou entrada/saída. Finalmente, a intenção
das variáveis globais utilizadas em cada procedimento foi explicitada através de
comentários afixados após o USE ONLY da variável global. Explicitando a ação da
variável no código, o fluxo de dados pode ser compreendido facilmente.
O código convertido foi estruturado em módulos temáticos e o programa principal
chama os módulos e os demais procedimentos. A Figura 5.2 mostra esta nova estrutura.
60
FIGURA 5.2. Estrutura do modelo Eta.
Os objetivos da reestruturação foram simplificar o entendimento da árvore de chamadas
dos procedimentos e reduzir a manipulação de arquivos. Foram criados quatro módulos
temáticos - Radiação, Turbulência, Convecção e I/O. Os três primeiros tratam dos
processos físicos do modelo e contém um único procedimento invocável externamente
ao módulo (os demais procedimentos são privados). Resultam 58 arquivos com 30217
linhas e a partição da árvore de chamadas em seis blocos: Inicialização, I/O, Convecção,
Turbulência, Radiação e Dinâmica.
Neste processo também foram encontradas diversas invasões de memória. O uso da
opção de compilação para detectar invasão de memória possibilitou a detecção. As
invasões foram removidas.
5.4.2 Análise de Dependências
Analisando as dependências de forma superficial, sem descer ao nível dos laços, pode-
se dizer que existem dependências de dados entre os processos físicos. Por exemplo, o
Cond. Iniciais/ Contorno
Arquivo de saída
Init Pdte
Vtadv Hzadv
Hzadv2 Pdnew
Rdtemp Gscond
Precpd Hdiff
Bocoh Pfdht
Ddamp Bocov
Procedimentos
Radt
Turb
Conv
Chko
Módulos
VariáveisGlobais
Módulos de Variáveis
ProgramaPrincipal
61
cálculo de chuva depende dos valores da umidade, temperatura, vento, dentre outros,
que são calculados por outros procedimentos.
Existem dependências de controle, pois os processos físicos não são chamados em todos
os passos de tempo. A execução dos processos físicos é controlada por condicionais e
são ordenados da seguinte forma: a cada 2 passos de tempo é calculada a advecção, a
seguir a radiação em cada 38 passos para ondas curtas e 76 passos para ondas longas, e
na seqüência a cada 4 passos de tempo os processos turbulentos, convecção e
precipitação. Os demais procedimentos da dinâmica e I/O são chamados em todos os
passos de tempo.
Identificar as direções de paralelismo independentes não requer o conhecimento
matemático das equações que regem o modelo. Nesse processo, adquire-se informações
essenciais de como os processos físicos são tratados. Para o modelo Eta foi adquirida a
informação de especialistas que os processos físicos são processo de colunas, ou seja,
são independentes nas latitudes (J) e longitudes (I). A dependência se restringe aos
níveis verticais (L). Essas direções independentes estavam explícitas no programa não
necessitando reestruturação do programa para identificá-las. Nos processos dinâmicos a
informação foi adquirida do texto do programa e também da análise de dependências
dos procedimentos. Um exemplo é demonstrado na advecção horizontal e vertical.
Na advecção horizontal, a influência da circulação de massa e de energia no cálculo das
tendências de temperatura, componente horizontal do vento (u,v), umidade e energia
cinética turbulenta, ocorre apenas na horizontal. Portanto não sofre dependência entre as
camadas verticais, mas sofre dependências nas direções das latitudes e longitudes como
mostra a Figura 5.3-a.
Já na advecção vertical o processo é inverso, os cálculos das tendências são feitos entre
camadas verticais, não possibilitando a paralelização nessa direção (Figura 5.3-b).
Entretanto nas direções das latitudes e longitudes não há dependências.
62
FIGURA 5.3a – Paralelização do laço L. FIGURA 5.3b – Paralelização do laço J.
Esses são alguns exemplos de como obter informações essenciais para descobrir as
direções que favorecem o paralelismo, sem conhecer as equações do modelo. Essa
informação é suficiente para o início do trabalho de paralelização.
5.5 Terceiro Passo – Estratégia Geral de Paralelização
Como a máquina alvo permite dois níveis de paralelismo as duas estratégias de
paralelização da metodologia são utilizadas.
5.5.1 Primeiro Nível – Vetorização
A primeira etapa deste trabalho foi priorizar quais procedimentos eram candidatos a
melhorar o grau de vetorização. Utilizando a listagem de medida dos tempos verificou-
se a coluna V.Op.Ratio, que indica a porcentagem de operações vetoriais no código.
Aliando-se essa coluna, com a coluna de medida do tempo gasto, mais a coluna de
Mflops que indica o número de operações de pontos flutuantes por segundo, e por fim
analisando a implementação do código, resulta uma ordem em que o trabalho foi
seguido. A Tabela 5.1 exemplifica os primeiros procedimentos que foram otimizados.
Analisando os primeiros resultados, conclui-se que o código foi concebido para uma
máquina de arquitetura escalar. No decorrer do código é observado que o cálculo é feito
para um ponto da superfície de cada vez. Para otimizá-lo foi necessário transformar as
variáveis escalares em vetores ou aumentar a dimensão dos vetores para o cálculo ser
feito na grade. Portanto é possível otimizar o cálculo vetorizando na latitude, na
i
l
j
n proc 2
. . .
1
j
i
1
2
n proc . . .
l
63
longitude ou em ambos. Em muitos casos a vetorização não é percebida pelo
compilador, devido à complexa implementação do código. A vetorização automática
tem limitações que muitas vezes podem ser contornadas.
TABELA 5.1 – Procedimentos candidatos à vetorização.
Procedimento Mflops (antes)
Mflops (depois)
V.Op.Ratio (antes)
V.Op.Ratio (depois) Técnica clássica
sfcdif 28 507 0.00 98.7 Subst. do código seqüencial: Variáveis escalares para rank=2
cucnvc 243.5 520.4 96.22 99.31 Quebra de laços
ttblex 28.2 369.9 19.28 99.96 Inserção de diretiva do compilador
vdifh 33.7 1056.6 43.44 99.45
Subst.do código seqüencial: Aumento do rank das variáveis de 1 para 3
vdifq 56.5 721.6 65.43 99.21
Subst. do código seqüencial: Aumento do rank das variáveis de 1 para 3
vdifv 33.2 1103.9 36.2 99.45
Subst.do código seqüencial: Aumento do rank das variáveis de 1 para 3
Aplicando as principais técnicas clássicas de otimização, é notável o aumento da
velocidade de processamento.
Dentre as técnicas mais aplicadas no decorrer do código estão as seguintes:
1. Aumento da dimensão do vetor;
2. Eliminação de desvios dentro de laços;
3. Inversão de laços para permitir a vetorização na maior dimensão do vetor;
4. Quebra de laços em laços menores separando os laços não vetorizáveis para
permitir a vetorização dos demais.
64
Essa primeira etapa requereu transformar laços que implementavam algoritmos
puramente seqüenciais, portanto, impedindo a vetorização e o paralelismo.
5.5.2 Segundo Nível – Paralelização Implementado por Diretivas
A segunda etapa do trabalho é a paralelização implementada por diretivas(OpenMP).
Com as direções de paralelismo previamente definidas, o paralelismo de segundo nível
foi aplicado seguindo os passos da estratégia de segundo nível.
a) O primeiro passo paraleliza aninhamentos de laços que não invocam
procedimentos e não requerem mudanças de algoritmo. A prioridade é paralelizar
laços mais externos possíveis, evitando assim o acesso sucessivo a bibliotecas do
sistema e reduzindo o gasto de tempo com inicialização de paralelismo. Essa
estratégia se aplica primeiramente aos procedimentos que não pertencem aos
módulos, considerando a ordem decrescente do tempo de processamento. Em
seguida aos procedimentos dentro dos módulos que não são chamados de dentro
de laços. A Figura 5.4 mostra o tempo de processamento do código.
Foram paralelizados procedimentos que fazem parte da dinâmica do modelo e que são
chamados em todos os passos de tempo. Esses ocupam 36,36% do tempo efetivo de
processamento do modelo de previsão.
Tempo gasto (cpu) %
36,36%
10,87%10,10%
37,18%
5,48%
Dinâmica Módulo Radiação Módulo ConvecçãoMódulo Turbulência Módulo Chko
FIGURA 5.4 – Tempo de processamento do código.
65
Em seguida foram paralelizados os laços dos procedimentos principais da física que não
invocam outros procedimentos. Apenas um procedimento de cada módulo da física é
visível externamente – esse procedimento é denominado procedimento principal do
módulo. Os demais procedimentos do módulo são privados, invocados pelo
procedimento principal.
Iniciamos pelo procedimento principal da turbulência, que ocupa 37,18% do tempo de
execução. Em seguida aplicamos o mesmo método à radiação, que ocupa 10,87% e à
convecção que ocupa 10,10%, respectivamente, do tempo total de execução. O módulo
de I/O não foi alterado.
b) O segundo passo paraleliza laços que invocam árvores de procedimentos. O
trabalho de transformar procedimentos ou árvores de procedimentos em puro foi
atribuído aos procedimentos principais dos módulos. O módulo da convecção foi
o primeiro a ser transformado em puro pela simplicidade da árvore de chamadas,
apesar do número de linhas de código (2095) não ser desprezível. A subrotina
principal do módulo cucnvc chama a subrotina ttblex que está dentro de um laço.
As variáveis são passadas por parâmetros, não havendo nenhuma violação das
regras citadas na metodologia (4.3.4.2 – b). O trabalho é apenas de verificação
das regras e definição das variáveis que devem ser replicadas para os processos
quando se paraleliza o laço.
O próximo módulo alvo foi o da turbulência, que exigiu bastante esforço para cumprir
as regras de procedimentos puros, pois sua árvore de chamadas é complexa. O laço
paralelizado foi o laço que chama a subrotina sflx que trata o modelo de superfície
(OSU). A Figura 5.5 apresenta a árvore de chamadas do módulo.
O módulo da turbulência possui aproximadamente 4997 linhas, sendo composta por
vinte e nove procedimentos. Nove destes procedimentos trabalham sobre campos totais.
Os demais trabalham sobre um ponto do terreno (cálculos de superfície e sub-
superfície). O procedimento principal da turbulência, turbl, trabalha sobre campos totais
e invoca todos os demais oito procedimentos que trabalham sobre campos totais. Sete
destes procedimentos não invocam outros procedimentos. O último (surfce) percorre
66
todos os pontos da superfície invocando para cada ponto um procedimento (sflx), que
por sua vez, invoca uma árvore com dezenove procedimentos (o modelo de superfície).
MODULE turb ! ! TURBL --+-- MIXLEN ! +-- PRODQ2 ! +-- DIFCOF ! +-- VDIFQ ! +-- SFCDIF ! +-- SURFCE --+-- SFLX --+-- REDPRM --+-- PRMSOI ! | | +-- PRMVEG ! | +-- TDFCND ! | +-- PENMAN ! | +-- CANRES ! | +-- NOPAC--+--SMFLX--+--DEVAP--+--WDFCND ! | | | +--TRANSP ! | | | +--SRT --+-- WDFCND ! | | | +--SSTEP--+--ROSR12 ! | | | ! | | +-- TDFCND ! | | +-- SHFLX +--HRTICE ! | | +--HRT --+-- TDFCND ! | | +--HSTEP--+--ROSR12 ! | | ! | +-- SNOPAC +--SMFLX-+--DEVAP--+--WDFCND ! | | +--TRANSP ! | | +--SRT --+-- WDFCND ! | | +--SSTEP--+--ROSR12 ! | | ! | +-- TDFCND ! | | ! | +-- SHFLX +--HRTICE ! | +--HRT --+-- TDFCND ! | +--HSTEP--+--ROSR12 ! | ! +-- VDIFH ! +-- VDIFV ! ! END MODULE turb
FIGURA 5.5 – Árvore de chamadas do Módulo da Turbulência.
A paralelização dos nove procedimentos que trabalham sobre campos totais requer
‘apenas’ paralelizar cada ninho de laços. Entretanto, o paralelismo de surfce é bastante
complexo, requer transformar sua árvore de procedimentos em puros.
Foram aplicadas as regras para transformá-los em procedimentos puros, e nesse
processo vale ressaltar alguns casos importantes:
− Foram eliminadas duas áreas common e a solução para suas variáveis foi
transformá-las em variáveis locais ou em argumentos;
67
− No caso do atributo save, foram eliminados dois casos onde o atributo estava
explícito no código, pois as variáveis não eram alteradas no escopo dos
procedimentos;
− Para o atributo data vale ressaltar um fato não evidente. Foram eliminados vinte
e três casos do atributo data, pois variáveis inicializadas por data são
automaticamente salvas. A solução foi transformá-los em constantes, pois não
eram alteradas.
O próximo módulo é a radiação, composto por 7828 linhas organizadas em vinte
procedimentos, como mostra a Figura 5.6. O procedimento principal da radiação, radtn,
é o único procedimento que recebe e trata os campos completos. Os demais
procedimentos ou trabalham em colunas verticais (uni-dimensional) ou em fatias de
latitude constante (bi-dimensional).
MODULE radt ! RADTN --+--GRADFS--+--HCONST ! | | ! | +--O3INT ! | | ! | +--CONRAD--+--TABLE ! +--SOLARD ! | ! +--ZENITH ! | ! +--O3CLIM ! | ! +--OZON2D ! | ! +--RADFS--+--CLO89 ! | ! +--LWR88--+--FST88--+--E1E290 ! | | ! | +--SPA88 ! | | ! | +--E290 ! | | ! | +--E2SPEC ! | | ! | +--E3V88 ! +--SWR93 ! END MODULE radt
FIGURA 5.6 – Árvore de chamadas do Módulo da Radiação.
O procedimento principal pode ser dividido em duas partes. A primeira parte apenas
prepara fatias de latitude para o cálculo da radiação. É composta por múltiplos laços e
invoca quatro procedimentos que estão fora de aninhamentos de laços. A segunda parte
68
possui um laço de 870 linhas que invoca a raiz do modelo de radiação do GFDL e o
procedimento que calcula ozônio. O modelo calcula a radiação para cada fatia de
latitude e invoca uma árvore de nove procedimentos com a raiz em radfs. É responsável
por 77% do tempo de execução do módulo.
Conseqüentemente, o esforço em paralelizar a radiação se concentrou em invocar,
simultaneamente, múltiplas cópias de radfs. Ou seja, em transformar radfs e sua árvore
de invocações em procedimentos puros.
Foram pontos relevantes desse trabalho:
− Eliminar quinze áreas common pois as variáveis eram somente de entrada
(intent(in));
− Eliminar vinte e dois casos do atributo equivalence
c) O terceiro passo reestrutura laços para permitir a paralelização de granulação
grossa. O objetivo desse passo é buscar melhoria de desempenho a custa de
refazer o paralelismo já aplicado em algumas partes do código. Após as duas
fases anteriores é feita uma avaliação para verificar o desempenho do código. Na
análise de desempenho detectou-se a necessidade de substituir o algoritmo em
precpd, buscando melhorar a distribuição de carga entre os processadores. O
algoritmo original distribuía colunas da atmosfera entre os processadores antes
de determinar quais colunas poderiam possuir precipitação de larga escala. O
novo algoritmo distribui exclusivamente as colunas que calculam a precipitação
(determinando as colunas antes de distribuí-las) equilibrando a carga entre os
processadores. Por facilidade de implementação, o cálculo da precipitação de
larga escala foi encapsulado em um novo procedimento, denominado
precpd_calc, que recebe um conjunto de colunas da atmosfera. Esse
procedimento foi codificado de forma a ser puro, permitindo a paralelização do
laço que o invoca.
69
A metodologia aplicada gerou resultados ao final de cada passo, indicando onde o
próximo esforço deve ser concentrado. Quando se passa de um passo para o outro, é
possível que seja necessário refazer partes do trabalho. Por exemplo, no segundo passo
é possível que novas alterações no corpo de laços, anteriormente seqüenciais, sejam
propagadas para laços que já foram paralelizados no primeiro passo.
A seguir apresentaremos os resultados da otimização vetorial e da aplicação do primeiro
e segundo passo da metodologia do paralelismo.
5.6 Quarto Passo – Resultados
5.6.1 Análise dos Resultados Numéricos
Os resultados numéricos da primeira etapa do trabalho, que corresponde ao primeiro
nível de paralelização – vetorização, foram alterados como era esperado. Programas
vetorizados alteram o resultado numérico devido ao uso de bibliotecas matemáticas
distintas de sua versão escalar. Essas diferenças são de arredondamento e em geral, são
verificadas após a integração do modelo para um limiar de tempo.
Executando os dois programas (original e paralelizado) compilados no modo escalar
(com opção ssafe) não existem diferenças, o que conclui que não foi introduzido
nenhum erro no código. Já para a execução compilada no modo vetorial (com opção
vsafe) existem diferenças de arredondamento.
Essas comparações podem ser vistas na Figura 5.7, que retrata a pressão da superfície
ao nível do mar para 48 horas de previsão. No gráfico da esquerda, o caso 0 (execução
puramente escalar) está representado por campo preenchido e o caso 1 (execução
vetorial) está representado por linha de contorno. Observe a conservação do padrão dos
campos meteorológicos. O gráfico da direita representa a diferença relativa entre os dois
campos.
Observe que o erro relativo após 48 horas de integração é da ordem de 0,03% da
pressão de superfície. Erros da mesma magnitude ocorrem nos demais campos.
70
FIGURA 5.7 – Comparações do código vetorizado e não vetorizado.
Para a segunda etapa – paralelização implementado por diretivas OpenMP, os
resultados numéricos não sofreram alteração. Logo, atingimos reprodutibilidade binária,
ou seja, os arquivos de saída são idênticos, bit a bit, para qualquer número de
processadores. A Figura 5.8 mostra o campo de pressão de superfície, após 48 horas de
previsão, para duas execuções: o caso 1 – execução vetorial e seqüencial (compilação
com opção vsafe e sem a opção openmp), e o caso 13 – execução vetorial e paralela com
8 processadores (compilação com opções vsafe e openmp). O gráfico da esquerda
representa o caso 1 como campo preenchido e o caso 13 como linha de contorno. O
gráfico da direita representa a diferença relativa entre os dois campos, ou seja, a
diferença é nula.
Os resultados desses dois experimentos demonstram que as diferenças numéricas entre a
versão original e a paralelizada devem-se apenas à vetorização. A ordem de grandeza
das diferenças é da ordem de 0,03% após 48 horas de previsão. O próximo experimento
demonstra que essa ordem de grandeza das diferenças é satisfatória.
71
FIGURA 5.8 – Comparação do código vetorizado e paralelizado (8 processadores).
Se fixar a versão original do ETA, fixar as opções de compilação (execução com
vetorização vsafe) e variar o compilador. Ocorrem diferenças numéricas após 72 horas
de integração, como mostra a Figura 5.9.
FIGURA 5.9 – Comparação de versões diferentes do compilador para o mesmo código.
72
O gráfico da esquerda representa a versão original – Oper1 como campo preenchido e a
versão original compilada com outra versão do compilador, como linha de contorno. O
gráfico da direita representa a diferença relativa entre os dois campos.
Diferenças da mesma ordem de grandeza são observadas quando se compara a versão
do código original com a versão final vetorizada e paralelizada para 72 horas de
previsão. Essa comparação é demonstrada na Figura 5.10. O gráfico da esquerda
representa a versão original – Oper2 como campo preenchido e a versão do código
paralelo compilado com a mesma versão do compilador, como linha de contorno. O
gráfico da direita representa a diferença relativa entre os dois campos.
Sumarizando, as diferenças numéricas introduzidas pela vetorização e paralelização
devem-se apenas à vetorização. A ordem de grandeza dessas diferenças é idêntica à
obtida por atualizações do compilador.
FIGURA 5.10 – Comparação de versões diferentes do código para o mesmo compilador.
Os resultados obtidos foram validados através de uma análise detalhada do
comportamento dos campos meteorológicos. Resultados muito próximos a esses foram
verificados nos demais campos do modelo e confirmam a validação.
73
5.6.2 Análise de Desempenho
5.6.2.1 Primeiro Nível
Segundo a metodologia, a análise de desempenho pode ser feita após cada passo.
Depois do código reestruturado e concluído o primeiro nível de paralelização –
vetorização, o desempenho foi avaliado.
A Figura 5.11 contrasta os tempos de execução antes e depois da reestruturação vetorial
que é a primeira etapa do trabalho. O objetivo principal nessa etapa é explorar ao
máximo cada processador vetorial.
Outro indicador de avanço é o aumento da velocidade de execução de 215 Mflops para
467 Mflops, que é 23,3% da velocidade máxima de um processador.
Tempo de Processamento
0
200
400
600
800
1000
Original Otimizado
RadiaçãoDinâmicaTurbulênciaConvecção
FIGURA 5.11 – Desempenho do modelo versão original versus versão com otimização vetorial.
Esse número contrasta favoravelmente com padrões internacionais (modelos de área
limitada atingem de 4 a 40% da velocidade máxima de processadores [16], [17], [18],
[19]). Entretanto, ainda há espaço para otimização. O tempo de execução vetorial (como
fração do tempo total) aumentou de 92% para 98%, o que é satisfatório. Já o tamanho
médio dos vetores aumentou de 84 para 111 elementos, que é insatisfatório face ao
tamanho ideal dos vetores (pelo menos 256 elementos [15]). A limitação no aumento do
74
tamanho médio dos vetores é devido à estrutura de dados original do Eta que contém
um “halo” nas dimensões das matrizes, para acomodar a grade Ε de Arakawa [20]. Em
conseqüência, índices de laços percorrem, de 1 até n, colunas consecutivas de matrizes
declaradas de 0 até n+1. Portanto duas instruções vetoriais consecutivas sobre colunas
consecutivas da matriz não serão encadeadas pois não atuam sobre posições
consecutivas da memória. Logo, não há como aumentar o tamanho dos vetores sem
modificar substancialmente a estrutura de dados, eliminando o “halo”.
5.6.2.2 Segundo Nível
O segundo nível de paralelização foi dividido em três passos, e os resultados foram
melhorando a cada passo da estratégia.
Os resultados atingidos são denotados pela aceleração (“speed-up”), definida como a
razão entre o tempo de execução seqüencial e o tempo de execução paralelo do mesmo
problema. Essa métrica depende do número de processadores utilizado – intuitivamente,
deseja-se que um programa execute n vezes mais rapidamente quando se utilizam n
processadores do que quando se utiliza um processador.
Para avaliar se esses resultados foram satisfatórios, podemos verificar a aceleração de
um programa utilizando n processadores. Entretanto, há outros fatores críticos a
considerar – em particular, quantificar a importância dos trechos do programa que ainda
não foram paralelizados, o que determina a fração seqüencial do tempo de execução.
Essa importância é medida pela Lei de Amdahl, que relaciona a aceleração máxima
teórica à fração do tempo de execução do programa que é executada seqüencialmente.
Se tivermos um número infinito de processadores, o tempo de execução da fração
paralela do programa tende a zero, e o tempo total passa a ser o tempo da fração
seqüencial. Logo, o menor tempo de execução possível é o tempo da fração seqüencial
– conseqüentemente, a aceleração está limitada à razão entre o tempo total e o tempo da
fração seqüencial do programa, mesmo usando um número ilimitado de processadores.
75
a) O primeiro passo da paralelização implementado por diretivas OpenMP gerou
resultados não muito significativos se medir o speedup para o código todo. Entretanto se
for analisado por partes, o desempenho passa ser razoável.
A Tabela 5.2 apresenta a importância de cada procedimento no tempo de execução
seqüencial da dinâmica do modelo (medido pelo percentual do tempo de execução gasto
no procedimento) e o ganho obtido com dois processadores.
TABELA 5.2 – Speedup da dinâmica com 2 processadores.
Procedimento % tempo Ganho (speedup)Pdte 1,1 1,85Pdnew 0,0 1,02Rdtemp 0,7 1,60Hdiff 12,1 1,96Bocoh 0,2 2,00Pfdht 15,4 1,85Ddamp 2,8 1,96Bocov 0,1 1,33Hzadv 31,0 1,98Vtadv 6,4 1,88Hzadv2 12,8 1,98Precpd 11,0 1,00Gscond 6,4 1,95Total 100,0 1,76
O ganho com dois processadores (1,76) é razoável. Entretanto, não há laços com
invocações a procedimentos a serem paralelizados, ou seja, o segundo passo da
paralelização OpenMP para a dinâmica é vazio. Os resultados demonstram que alguns
procedimentos devem ser reescritos, durante a execução do terceiro passo (na ordem de
importância, precpd e pfdht), eliminando construções seqüenciais e/ou substituindo
algoritmos.
Os laços do procedimento principal do módulo da convecção (cucnvc) passíveis de
paralelização nesse passo da metodologia foram paralelizados. A invocação do
procedimento dentro de laço permaneceu seqüencial. Isto proporcionou o ganho de 1,61
com dois processadores. Esse ganho torna-se razoável quando se considera o tempo de
execução do ninho de laços que invoca o procedimento ttblex que não foi paralelizado.
76
Todos os laços do módulo da turbulência foram paralelizados, exceto a invocação a sflx
e sua árvore de procedimentos. Os ganhos obtidos (para dois processadores) e a
importância relativa de cada procedimento (medida pelo percentual do tempo de
execução seqüencial da turbulência) encontram-se na Tabela 5.3. A soma dos
percentuais dos tempos de execução indica que o paralelismo foi instalado em apenas
37% do tempo de execução da turbulência.
TABELA 5.3 – Speedup do módulo da Turbulência com 2 processadores.
Procedimento % tempo Ganho (speed-up)Turbl 14,8 1,99Mixlen 4,9 1,66Prodq2 3,9 1,84Difcof 1,7 1,96Vdifq 1,9 2,00Sfcdif 3,6 1,85Surfce 4,7 1,00Vdifh 1,1 1,90Vdifv 0,9 1,90
É importante perceber que da ordem de 63% do tempo de execução está na árvore de
procedimentos que trata da superfície.
Os laços do procedimento principal do módulo de Radiação (radtn) foram paralelizados
exceto o laço que invoca os procedimentos responsáveis pelo modelo de radiação
(radfs) e o cálculo do ozônio (ozon2d). Isto proporcionou ganho de 1,3 com dois
processadores. O baixo resultado deve-se à não paralelização do laço citado acima.
Depois de analisado o desempenho por módulos do modelo, foi possível fazer uma
análise global do desempenho do modelo para o primeiro passo. A Figura 5.12 mostra a
curva de speedup para o código do modelo Eta.
Resulta que o modelo executa 1,56 vez mais rápido com 2 processadores, 2,28 vezes
mais rápido com 4 processadores, 2,9 vezes mais rápido com 6 processadores e 3,18
vezes mais rápido com 8 processadores. A aceleração obtida com 8 processadores torna-
se razoável para a primeira etapa.
77
Desempenho por Módulo - Primeira etapa OpenMP
0,00
0,50
1,00
1,50
2,00
2,50
3,00
3,50
4,00
4,50
5,00
1 2 4 6 8
Nº processadores
Spe
edup
Conv Radt Turb Dinâmica Total Init+I/O
FIGURA 5.12 – Desempenho do código após primeiro passo da paralelização OpenMP.
b) O segundo passo da paralelização gerou resultados mais significativos quando se
analisa cada módulo separadamente. Como os módulos de inicialização e I/O não foram
paralelizados, essa fração serial limita o desempenho global. A Figura 5.13 apresenta a
curva de speed-up de 1 a 8 processadores, por módulo paralelizado após paralelização
dos laços que invocam procedimentos e após o terceiro passo da paralelização.
Desempenho do Eta - Final OpenMP
0,00
1,00
2,00
3,00
4,00
5,00
6,00
7,00
1 2 3 4 5 6 7 8Nº de processadores
Spee
dup
init+i/o radt conv turb dinâmica Total
FIGURA 5.13 – Desempenho do Código paralelo OpenMP.
78
c) O terceiro passo da paralelização OpenMP que trata da reestruturação de laços foi
aplicado a subrotina precpd que faz parte da dinâmica do modelo. O ganho foi
significativo para este caso, o speedup que não passava de 1,03 para 6 processadores
passou a alcançar 3,78. Essa implementação já está incorporada nos resultados da
dinâmica que são mostrados a seguir. O resultado mostra que o modelo executa mais
rápido, 1,82 vez com 2 processadores, 3,04 vezes com 4 processadores, 3,89 vezes com
6 processadores e 4,55 vezes com 8 processadores.
Para avaliar se a aceleração é satisfatória, temos fatores críticos a considerar – em
particular, quantificar a importância dos trechos do programa que ainda não foram
paralelizados, o que determina a fração seqüencial do tempo de execução, segundo a Lei
de Amdahl. Como a fração seqüencial do código (inicialização e I/O) ocupa 4% do
tempo total, a aceleração máxima teórica é 6,25 com 8 processadores (pois os 8
processadores podem acelerar 96% do tempo de execução do programa; dessa forma, o
tempo de execução está limitado a 96%/8+4% do tempo seqüencial, ou seja, 16% do
tempo seqüencial).
Nessa ótica, a aceleração obtida com 8 processadores tornou-se razoável. A Figura 5.14
mostra o crescimento da fração seqüencial do código (Init+I/O) com o aumento do
número de processadores. O ganho obtido pela combinação dos dois níveis de
paralelismo é satisfatório.
0%10%20%30%40%50%60%70%80%90%
100%
1 2 3 4 5 6 7 8
dinamica
turb
conv
radt
init+i/o
FIGURA 5.14 – Medida de tempo por módulos.
79
O tempo de processamento do código Eta paralelo, rodando com 8 processadores, é 7,6
vezes mais rápido que a versão original em Fortran 77 (Tabela 5.4). Esse experimento
foi realizado para previsão de 3 dias de integração, numa resolução de 40Km, com 38
níveis na vertical e sobre uma grade de 119 x 249 pontos, cujo domínio varia na
longitude 35W a 85W e na latitude de 10N a 45S.
TABELA 5.4 – Comparação entre as versões do Código.
Versão Tempo (s) Razão
Original 3967 7,60
Paralelo nível 1 2378 4,55
Paralelo nível 2 (8Proc) 522 1,00
A seguir, avaliamos o uso de memória. Como o paralelismo OpenMP introduz áreas de
trabalho locais a cada processador, espera-se aumento no uso de memória com o
aumento do número de processadores. Admitindo que a memória dependa linearmente
do número de processadores, aproximamos essa função por mínimos quadráticos sobre
os dados experimentais, obtendo M = 19,45*P + 335,75, onde M é a quantidade de
memória em MBytes e P o número de processadores utilizados.
Resumindo, o aumento do número de processadores acarreta aumento do uso de
memória, à razão de 5,79% por processador, na resolução utilizada. Consideramos este
custo aceitável face à redução do tempo de execução (Tabela 5.5).
TABELA 5.5 – Uso de memória.
Processadores Memória (MB)Original
1 2 4 6 8
757 354 376 414 452 491
80
Surpreendentemente, a versão paralela requer de 46,4% a 64,8% da memória utilizada
pela versão original. Essa redução deve-se à alocação dinâmica de memória, permitida
pelo compilador Fortran 90 no uso do OpenMP para programas escritos em Fortran 90,
portanto inexistente na versão original. As variáveis são alocadas no início das regiões
paralelas e dealocadas no seu término, automaticamente, devido ao uso de OpenMP.
Ou seja, a versão original aloca toda a memória no início da execução, mantendo-a
alocada durante toda a execução, enquanto a versão paralela acrescenta e retorna
memória conforme a solicitação do procedimento que está sendo executado no
momento. Em conseqüência, a cada instante da execução original, da ordem de 50% da
memória alocada não está sendo utilizada.
81
CAPÍTULO 6
CONCLUSÕES E TRABALHOS FUTUROS
A metodologia proposta nesta dissertação facilita a paralelização de programas
científicos pré-existentes, substituindo o estudo do modelo matemático e dos métodos
numéricos pelo alvo desse estudo – a obtenção das direções independentes do programa.
Atinge-se esse conhecimento através de informações obtidas de especialistas ou de
comentários no programa.
Entretanto essas informações não garantem a paralelização, pois detalhes de
programação podem inibir direções promissoras de paralelismo. A análise de
dependências resultante do estudo da implementação do programa é passo
indispensável, tanto para confirmar direções promissoras quanto para obtê-las.
A metodologia apresenta técnicas necessárias para prover a paralelização, permitindo
que o programador aplique-as gradativamente a trechos selecionados do programa,
obtendo resultados a cada aplicação. Os passos da metodologia são:
1. Criar um ambiente de trabalho: árvore de chamadas do programa e medidas de
desempenho;
2. Análise de dependências e do fluxo de dados: A análise de dependências é o
processo que viabiliza a identificação das direções independentes para obter
paralelismo, podendo ter essa informação prévia ou não. Quando a informação
já foi dada, o trabalho é de verificação e validação dessa informação na
implementação do programa. Se não estão contidas de forma explícita, é
necessária a reestruturação do programa para torná-lo paralelizável. Na análise
do fluxo de dados é primordial explicitar o fluxo de dados para facilitar o
entendimento.
3. Estratégia geral de paralelização: aplicar técnicas de otimização de programas
seqüenciais e paralelismo de laços: a) que não invocam procedimentos; b) que
invocam procedimentos; c) reestruturação para prover paralelismo de granulação
mais grossa;
4. Análise dos resultados numéricos e de desempenho.
82
A metodologia foi validada pela sua aplicação ao modelo regional de previsão de tempo
(ETA) operacional do CPTEC.
Primeiramente a reestruturação do programa gerou modificações computacionais
profundas para prover paralelismo de dois níveis – vetorização e paralelismo
implementado por diretivas OpenMP, que viabilizou a portabilidade do programa. O
aumento da velocidade, usando 8 processadores, é bastante significativo para os
módulos do modelo, tendo alcançado um speedup de 4,98 para a convecção, 5,15 para
os processos dinâmicos, 6,05 para a turbulência e 6,18 para a radiação. Já o speedup
total alcançou 4,55 para 8 processadores devido ao módulo de inicialização e I/O
permanecerem seqüenciais.
Foi constatada a redução no uso da memória em aproximadamente 50% da versão
original. O aumento do uso da memória foi gradativo para mais de 1 processador,
entretanto usando 8 processadores não atingiu 65% da versão original. Isso foi devido
ao uso das diretivas OpenMP num programa codificado e compilado em Fortran 90, que
permite alocação dinâmica. Apesar de não estar explícita no programa, a alocação
dinâmica ocorreu implicitamente ao abrir e fechar regiões paralelas em OpenMP.
Trabalhos futuros promissores ocorrem em duas direções. Primeiro, estender a
validação da metodologia, aplicando-a em outros problemas científicos seqüenciais ou
em problemas já paralelizados que não atingiram o desempenho desejado. Segundo,
avaliar a possibilidade de estender a metodologia para três níveis de paralelismo,
abrangendo máquinas de memória distribuída.
Quanto ao modelo Eta, ainda há espaço para melhorias nos desempenhos seqüencial e
paralelo.
Melhorar o desempenho seqüencial requer aumentar o grau de vetorização ou aumentar
o tamanho médio dos vetores. O grau de vetorização pode ser ampliado pela vetorização
do modelo de superfície, atualmente escalar. Aumentar o tamanho médio dos vetores
requer reestruturação substancial da estrutura de dados original (remoção de “halos”)
para encadear instruções vetoriais.
Na paralelização, o caminho mais promissor é paralelizar o módulo de I/O. Isso requer
modificar a estrutura dos arquivos de saída, de seqüencial para acesso direto, permitindo
83
que processadores distintos escrevam simultaneamente em registros distintos do mesmo
arquivo.
84
85
REFERÊNCIAS BIBLIOGRÁFICAS
1 - OpenMP Architecture Review Board. OpenMP Fortran application program interface: version 1.1. [S.l: S.n], 1999. 76p.
2 - Allen, R.; Kennedy, K. Optimizing compilers for modern architectures: adependence-based approach. [S.l.]: Morgan Kaufmann Publishers, 2001. 876p.
3 - Tuccillo, J.J. International Business Machines (IBM), 2002. [Comunicação pessoal].
4 - Missirlis, N.M., et al. The weather forecasting system SKIRON. Athens: [S.n], 1998. v.4, 112p.
5 - Flynn, M.J. Some computer organizations and their effectiveness. IEEE transactions on computing, v.C-21, n.9, p. 948-960, 1972.
6 - Doud, K.; Severance, C. R. High performance computing. 2.ed. Sebastopol: O´Reilly& Associates, 1998. 446p.
7 - Sato, L.M; Midorikawa, E.T. Aspectos de programação paralela: uma visão prática. In: Jornada EPUSP/IEEE em sistemas de computação de altodesempenho, 2., 1992. Anais... São Paulo: IEEE, 1992.
8 - Hennessy, J.L.; Patterson, D.A. Computer architecture: a quantitative approach. Maddison: Morgan Kauffman Publishers, 1995. 760 p.
9 - Karp, A.H. Program for parallelism. [S.l.]: IBM Palo Alto Scientific Center,1987.
10 - Gropp,W.; Lusk, E.; Skijellum, A. Using MPI: portable parallel programming with the message-passing interface. 2.ed. [S.l: S.n.], 1999. 371p.
11 - ANSI Accredited Technical Subcomittee X3J3. International standard programming language Fortran. 1996. Disponível em: <http://tupinamba/f90/ISO/isof90.htm> . Acesso em: 12 fev. 1999.
12 - Tomita, S.S.; Rodrigues, L.F.; Panetta, J. Paralelização em dois níveis do modelo regional de previsão de tempo Eta. In: Workshop em Sistemas Computacionais de Alto Desempenho, 4., 2003, São Paulo. Anais... São Paulo: Grimart, 2003. p. 96-100.
13 - Mesinger, F.; Janjic, Z.I.; Nickovic, S.; Gavrilov, D., Deaven, D.G. The step-mountain coordinate: model description and performance for cases of Alpine leecyclogenesis and for a case of appalachian redevelopment. Monthly WeatherReview, v. 116, p. 1493-1518, 1988.
14 - Black, T.L. The new NMC mesoscale Eta model: description and forecastexamples. Weather and Forecasting, v. 9, p. 265-278, 1994.
15 - NEC. Sx-4 series applications training. [S.l.:S.n], 1998.
86
16 - Diehl, T; Gülzow, V. Performance of the parallelized regional climate modelREMO. In: ECMWF Workshop on the Use of Parallel Processors in Meteorology,1998, Reading, UK. Proceeding... [S.l.]: European Centre for Medium-range Weather Forecasts, 1998. p. 181-191.
17 - Schätter, U.; Krenzien, E. Performance requirements for DWD´s new models, em Towards Teracomputing. In: ECMWF Workshop on the Use of Parallel Processors in Meteorology, 1999, Reading, UK. Proceedings... [S.l.]: European Centre for Medium-range Weather Forecasts, 1999. p. 213-219.
18 - Salmond, D. et al. Performance of the parallelized regional climate model REMO, em Towards Teracomputing. In: ECMWF Workshop on the Use of Parallel Processors in Meteorology,1999, Reading, UK. Proceedings... [S.l.]: European Centre for Medium-range Weather Forecasts, 1999. p. 220-230.
19 - Jorgensen, J.U. Application of plug and play FORTRAN at the danish meteorological institute, em towards teracomputing. In: ECMWF Workshop on the Use of Parallel Processors in Meteorology, 1999, Reading, UK. Proceedings... [S.l.]: European Centre for Medium-range Weather Forecasts, 1999. p. 314-330.
20 - Arakawa, A.; Lamb, V.R. Computacional design of the basic dynamical processes of the UCLA general circulation model. Methods in Computational Physics, v. 17, p.173-265, 1977.
21 - Gadd, A.J. A split-explicit integration scheme for numerical weather prediction.Quarterly Journal Royal Meteorological Society, v. 104, p. 569-582, 1978.
22 - Mellor, G.L.; Yamada, T. A hierarchy of turbulence closure models for planetaryboundary layers. Journal Atmospheric Science, v. 31, p. 1791-1806, 1974.
23 - Fels, S.B.; Schwarzkopf, M.D. The simplified exchange approximation: a new method for radiative transfer calculations. Journal of Atmospheric Science, v. 32, p. 1475-1488, 1975.
24 - Lacis, A.A.; Hansen, J.E. A parameterization of the absortion of solar radiation inthe earth's atmosphere. Journal of Atmospheric Science, v. 31, p. 118-133,1974.
25 - Janjic, Z.I. The step-mountain Eta coordinate model: further developments of the convection, viscous sublayer, and turbulence closure schemes. JournalAtmospheric Science, v. 122, p. 927-945, 1994.
26 - Chen, F.; Mitchell, K.; Janic, Z.; Baldwin, M. Land surface parameterization in the NCEP Mesoescale Eta Model. Research Activities in Atmospheric and Oceanic Modelling, n.23, p.4.4, 1996.
27 - Janjic, Z.I. Pressure gradient force and advection scheme used for forecastingwith steep and small scale topography. Contributions to Atmospheric Physics, v. 50, p. 186-199. 1977.
87
28 - Lazic, L. et al. Documentation of the UB/NMC eta model. Belgrade: [S.n], 1990. p. 167
29 - Janjic, Z.I. Forward-backward scheme modified to prevent two-grid-internal noise and its application in sigma coordinate models. Contributions of Atmospheric Physics, v. 52, p. 69-84, 1979.
30 - Mesinger, F. A blocking technique for representation of mountains in atmosphericmodels. Rivista Meteorogia Aeronautica, v. 44, p. 195-202, 1984.
88
89
APÊNDICE A
DESCRIÇÃO DO MODELO REGIONAL DE PREVISÃO DE TEMPO – ETA
1. Características Gerais do Modelo ETA
Este apêndice apresenta de forma sucinta, as principais características do modelo de área limitada Eta, somente para efeito ilustrativo, pois o desenvolvimento do trabalho é puramente computacional, não envolvendo a formulação matemática e os métodos numéricos empregados.
O modelo Eta foi desenvolvido na Universidade de Belgrado em cooperação com o Instituto de Hidrometeorologia da Iugoslávia e o NCEP National Center for Environmental Prediction em Washington [13] [14]. Consiste em uma grade Ε de Arakawa [20] e coordenada vertical η [30]. A integração no tempo utiliza a técnica de Split-Explicit [21], os processos turbulentos são tratados através do esquema de Mellor-Yamada [22] e o esquema de parametrização de ondas longa [23] e curta [24] foi desenvolvido pelo Geophysical Fluid Dynamics Laboratory. O modelo utiliza um esquema de Betts-Miller modificado para parametrizar a convecção [25] e o balanço hídrico é representado pelo esquema OSU [26].
A versão operacional deste modelo no CPTEC utiliza resolução horizontal de 40 Km e 38 níveis verticais. As condições iniciais e de contorno são geradas pelo modelo de circulação Global do CPTEC (MCG).
A seguir alguns aspectos mais relevantes do modelo, como a grade horizontal, coordenada vertical, topografia, esquema de integração e as equações básicas do modelo serão apresentados.
2. Grade Horizontal
A discretização horizontal do modelo usa a grade semi-escalonada Ε de Arakawa sobre um sistema de coordenadas de latitude e longitude transformadas. As coordenadas geográficas são rotacionadas de forma que a intersecção do equador com o meridiano de Greenwich coincida com o centro do domínio do modelo. Essa transformação resolve problemas da distribuição não uniforme dos pontos de grade nas altas latitudes com relação ao equador. A Figura A1 apresenta a grade horizontal.
Nos pontos de massa (denotados por h) estão representados os campos de temperatura, pressão da superfície, umidade específica, velocidade vertical, água precipitável e energia cinética turbulenta enquanto que nos outros pontos (denotados por ν) estão representadas as componentes horizontais do vento. A distância que determina a resolução horizontal do modelo é representada por d.
90
FIGURA A1 – Grade horizontal Ε de Arakawa.
A Figura A1 mostra uma grade subdividida em quatro sub-grades, as variáveis de velocidade do vento são calculadas ao longo da borda de cada grade, enquanto que as variáveis de massa são definidas no centro da grade. Há Im latitudes, Jm longitudes e Lm níveis verticais.
3. Coordenada Vertical
A coordenada vertical Eta (η) foi proposta por Mesinger [30] para solucionar problemas relacionados com áreas de montanhas que ocorrem em coordenadas sigma (σ). Nas montanhas íngremes [27] é detectada a contribuição irreal para o gradiente de pressão quando em coordenada sigma (σ). A principal vantagem da coordenada Eta (η) é que essas estão dispostas quase na horizontal, tanto nas áreas planas quanto nas áreas de montanhas. Já a coordenada sigma (σ) acompanha o relevo. A coordenada vertical Eta (η) é fundamentada na normalização da pressão e é definida por:
sPPPP
TS
T ηη −−= (2.1)
onde
Trf
Tzrf
PPPZP
s −
−= )0(
)(η (2.2)
Pontos de massa (h)
Pontos de velocidade (ν)
Sub-grade
d
Im
Jm
Área de Halo
Im +1
Jm+1
91
P – pressão no ponto PT – pressão no topo da atmosfera do modelo Ps – pressão da superfície Zz – altura geométrica Prf – pressão de referência em função da altitude O modelo verticalmente apresenta um número de camadas (L) que não são distribuídas uniformemente. As camadas próximas à superfície são dispostas com menor espaçamento entre si, aumentando à medida que se aproximam do topo da atmosfera. Isso permite cálculos mais precisos na camada limite planetária. No esquema da topografia apresentado na Figura A2, verificamos a representação dos níveis Eta (η) e sua distribuição na vertical.
4. Topografia
A representação topográfica do modelo Eta é diferente dos outros modelos numéricos devido aos sistemas de coordenadas horizontais e verticais usados. É determinada por um esquema de degraus discretos, com a altura de cada degrau determinada pelo método da Silhueta [28]. A altura do topo dos degraus coincide exatamente com a interface da camada vertical do modelo. A Figura A2 ilustra este esquema.
FIGURA A2 - Representação do esquema de degraus de montanhas e coordenada Eta. Os cálculos das variáveis, como a temperatura (T) e a componente horizontal de velocidade do vento, são determinados nos níveis intermediários das camadas verticais. A energia cinética turbulenta, a velocidade vertical (ω) e geopotencial (Φ), que é função da pressão de superfície, são determinadas nas interfaces das camadas. Para preservar propriedades de conservação dos esquemas de diferenças finitas usados, os valores de velocidade situados nos vértices de um degrau da topografia são fixados como zero.
η=1
Pontos de massa (h)Pontos de velocidade (ν)
Pr (Zs) Pr =1013hPaZs = 0
η=0.8
η=0.9
η=0.7
92
5. Esquemas de Integração e Equações Básicas
As equações básicas que regem o modelo Eta são: a equação da conservação da quantidade de movimento, da termodinâmica, da continuidade e da hidrostática [28]. As variáveis prognósticas (que variam com o tempo), são: temperatura, umidade específica, componentes horizontais do vetor velocidade (vento), energia cinética turbulenta, pressão de superfície e água precipitável.
A integração no tempo utiliza a técnica de 'Split-explicit' [21] onde os termos, devido ao ajuste pelas ondas de gravidade inerciais são integrados separadamente dos termos devido a advecção. Um esquema 'Forward-Backward' modificado por Janjic [29] trata dos termos responsáveis pelo ajuste ondas de gravidade inerciais, enquanto o esquema 'Euler-Backward' [28] modificado trata dos termos de advecção horizontal e vertical. O passo de tempo fundamental do modelo é o do ajuste de ondas de gravidade inerciais, que equivale à metade do passo de tempo da advecção.
93
APÊNDICE B
DESCRIÇÃO DA ARQUITETURA DAS MÁQUINAS NEC SX-4/SX-6
1. Características Gerais
Este apêndice apresenta de forma geral os principais aspectos das máquinas utilizadas para aplicação da metodologia. Suas características indicam a capacidade total de processamento visando elucidar os resultados obtidos no capítulo 5. As máquinas utilizadas para essa aplicação estão locadas no CPTEC/INPE que operacionaliza a previsão de tempo e de clima para o território nacional. O CPTEC possui um NEC SX-4 com a configuração de 1 nó de memória compartilhada (8 Gbytes) com 8 processadores com capacidade de processamento de 2 GFLOPS por processador, totalizando 16 GFLOPS. Possui também um NEC SX-6 de arquitetura híbrida: 4 nós com 8 processadores com capacidade de 8GFlops por processador, totalizando 64 GFLOPS, e memória compartilhada (32 Gbytes) no nó e memória distribuída entre os nós. A troca de mensagens entre os nós é feito por um switch crossbar internode (IXS). Os detalhes da arquitetura da série SX será citada a seguir.
1.1 Processador Vetorial Paralelo – SX
A NEC apresenta uma série SX de sistemas de supercomputação de alto desempenho que utilizam sistema operacional SUPER-UX baseado em Unix. O SX-4 foi o primeiro supercomputador vetorial multiprocessado que alcança um nível de desempenho em TFLOPS (Tera of Floating-point Operations Per Second). Todos os modelos utilizam processadores com tecnologia CMOS refrigerados a ar. Cada processador chega a atingir 2GFlops de desempenho vetorial. O paralelismo interno existente em cada processador fornece resultados de 16 operações de pontos flutuantes a cada 8 nano segundos. A série SX tem 4 unidades funcionais, cada uma com 8 pipelines vetoriais totalizando 32 pipelines que pode ser visto na Figura B1. Quatro instruções vetoriais podem ser executadas concorrentemente: add, multiply, divide, e logical.
FIGURA B1 – Características da unidade vetorial do SX.
FONTE: “Supercomputer SX Series”- NEC catalog.
94
Essas instruções encadeadas maximizam a eficiência da unidade vetorial. Para a vetorização ser efetuada é necessário um vetor com dimensão mínima de 6 elementos que é o padrão adotado, podendo ser alterado conforme a opção de compilação utilizada e no máximo de 2,1x109 aproximadamente. Entretanto para alcançar a máxima eficiência é necessário que os vetores de trabalho sejam de 256 elementos que é o tamanho de um registrador vetorial da série SX.
O SX é provido de uma unidade superescalar que pode ter um desempenho escalar de 250 MFlops. A unidade escalar também distribui todas as instruções para a unidade vetorial. Características avançadas tal como branch prediction hardware, out-of-order instructions são expandidos para ambas unidades: escalar e vetorial. Instruções de alto desempenho de 128 kilobytes e um cache para dados escalares também foram integrados ao projeto (Figura B2).
FIGURA B2 – Características da unidade superescalar do SX.
FONTE: “Supercomputer SX Series”- NEC catalog.
Uma outra característica de cada processador é a compatibilidade com formatos de dados IEEE, IBM, e Cray proporcionando também a flexibilidade de uso dos dados em 64 bit ou 32 bit desde que sejam selecionados como padrão.
Cada processador inclui um componente integrado vetorial e escalar sendo que cada processador pode acessar diretamente toda memória principal na configuração de até 32 processadores. Todos os 32 processadores podem ser eficientemente usados em um simples processo paralelo. Cada processador possui 72 registradores vetoriais de 256 elementos cada, e 128 registradores escalares. A configuração da CPU pode ser vista na Figura B3.
Além da memória principal, os modelos da série SX com memória SSRAM podem ser configurados com até quatro unidades de memória extendida (XMU). Cada XMU pode ter até 8 Gbytes de capacidade e funções como um disco de alta velocidade numa razão de transferência de 4 Gbytes por segundo. O uso da XMU pode melhorar substancialmente o desempenho de I/O, proporcionando economia de espaço em cache como também apresenta alta velocidade no sistema de arquivos.
95
FIGURA B3 – Características da CPU do SX.
FONTE: “Supercomputer SX Series”- NEC catalog.
O processador NEC tem, de forma geral, subsistemas de memória non-blocking que são substancialmente mais avançados que outros existentes. A bandwidth de memória é tipicamente de uma ordem de grandeza muito maior que o realizado num microprocessador baseado num sistema de memória cache. As memórias podem concorrentemente suportar 16 Gbytes de dados por segundo em cada processador. A memória principal pode ser configurada até 16 Gbytes usando SSRAM e até 32 Gbytes usando SDRAM.
Um sistema multi-nó é configurado por uma interconexão dos nós simples via um crossbar switch de alta velocidade (IXS) como mostra a Figura B4. Tem capacidade de interconexão de até 1024 CPUs e o desempenho vetorial pode atingir 8TFLOPS.
FIGURA B4 – Configuração do sistema multi-nó do SX-6.
FONTE: “Supercomputer SX Series”- NEC catalog.
O internode crossbar switch pode ser usado para configurar o sistema de multi-nó do sistema. Ele fornece um máximo de rendimento de 1024 Gbytes/segundo em uma conexão inter-nó e conecta os nós via interface de alto desempenho de 8 Gbytes/segundo.
96
Em resumo, a série SX oferece uma arquitetura característica que minimiza o tempo de execução de melhora o rendimento do sistema:
a. O alto desempenho e alta capacidade da XMU reduz significantemente o processo de I/O;
b. O sistema maximiza a porcentagem de programas que podem ser executados por instruções vetoriais, dessa forma reduz substancialmente o tempo de execução;
c. A arquitetura superescalar reduz o tempo gasto por um processador escalar;
d. O sistema executa concorrentemente instruções vetoriais e escalares. Além disso, a melhoria da sua capacidade computacional é possível através do uso de inúmeros registradores vetoriais e escalares, de um branch prediction de alta velocidade, de instrução out-of-order expandida e de pipelines escalares;
e. O rendimento do sistema é maximizado pela configuração dos multi-processadores.
PUBLICAÇÕES TÉCNICO-CIENTÍFICAS EDITADAS PELO INPE
Teses e Dissertações (TDI)
Manuais Técnicos (MAN)
Teses e Dissertações apresentadas nos Cursos de Pós-Graduação do INPE.
São publicações de caráter técnico que incluem normas, procedimentos, instruções e orientações.
Notas Técnico-Científicas (NTC)
Relatórios de Pesquisa (RPQ)
Incluem resultados preliminares de pesquisa, descrição de equipamentos, descrição e ou documentação de programa de computador, descrição de sistemas e experimentos, apresenta- ção de testes, dados, atlas, e docu- mentação de projetos de engenharia.
Reportam resultados ou progressos de pesquisas tanto de natureza técnica quanto científica, cujo nível seja compatível com o de uma publicação em periódico nacional ou internacional.
Propostas e Relatórios de Projetos (PRP)
Publicações Didáticas (PUD)
São propostas de projetos técnico-científicos e relatórios de acompanha-mento de projetos, atividades e convê- nios.
Incluem apostilas, notas de aula e manuais didáticos.
Publicações Seriadas
Programas de Computador (PDC)
São os seriados técnico-científicos: boletins, periódicos, anuários e anais de eventos (simpósios e congressos). Constam destas publicações o Internacional Standard Serial Number (ISSN), que é um código único e definitivo para identificação de títulos de seriados.
São a seqüência de instruções ou códigos, expressos em uma linguagem de programação compilada ou inter- pretada, a ser executada por um computador para alcançar um determi- nado objetivo. São aceitos tanto programas fonte quanto executáveis.
Pré-publicações (PRE)
Todos os artigos publicados em periódicos, anais e como capítulos de livros.