Utilização de Medidas de Previsibilidade em Sinais de Voz ...
Escalonamento de tarefas em arquiteturas heterogêneas - APUS
Transcript of Escalonamento de tarefas em arquiteturas heterogêneas - APUS
ANDERSON UILIAN KAUER
ESCALONAMENTO DE TAREFAS EM ARQUITETURAS HETEROGÊNAS – APUS
Trabalho de conclusão apresentado para a banca examinadora do curso de Ciência da Computação do Centro Universitário La Salle - Unilasalle, como exigência parcial para a obtenção do grau de Bacharel em Ciência da Computação.
Orientação: Profº Dr. Mozart Lemos de Siqueira
CANOAS, 2012
ANDERSON UILIAN KAUER
ESCALONAMENTO DE TAREFAS EM ARQUITETURAS HETEROGÊNA S – APUS
Trabalho de Conclusão apresentada ao Centro Universitário La Salle – UNILASALLE como requisito parcial para obtenção do grau de bacharel em Ciência da Computação
Aprovado em 5 de dezembro de 2012
BANCA EXAMINADORA
____________________________________________________
Prof. Me. Eder Stone Fontoura
Unilasalle
____________________________________________________
Prof. Me. Rafael Kunst
Unilasalle
AGRADECIMENTOS
Agradeço à minha família, em especial à minha mãe, agradeço eternamente pela mi-
nha educação e por seu exemplo de comprometimento e perseverança fez e continua fazendo
com que seu filho nunca desista dos objetivos. Ao meu pai, da mesma forma, agradeço pelo
exemplo de luta, humildade e honestidade. Aos meus irmãos pelo apoio e incentivo nestes di-
as intermináveis que foram necessários para que este trabalho se tornasse possível.
Aos meus amigos, em especial à Letícia Santos e Francielle Vasconcelos que sempre
me ajudaram a superar os momentos de dificuldades. À Renata Fraga Cardoso, Bruna Bortoli
e Miniê Takesako pelo apoio e companheirismo de tantos anos. Agradeço a Marco Antônio de
Assunção que foi extremamente importante para o desenvolvimento deste trabalho. À Cindy
Francês e Edsandro Freitas que prestaram sua contribuição sempre que necessária. Aos meus
inúmeros colegas, muito obrigado pelo companheirismo.
Finalmente, agradeço ao professor Dr. Mozart Lemos de Siqueira, meu orientador, por
acreditar em mim e propiciar a superação dos inúmeros momentos de dúvida, e aos professo-
res Pós-Dr. Pedro Velho, Dra. Patrícia Kayser e Me. Abrahan Lincoln por contribuírem de al-
guma forma para o desenvolvimento do mesmo.
“Não importa quanto a vida possa ser ruim, sempre existe algo que você pode fazer, e triunfar”
Stephen Halking
RESUMO
Processadores com múltiplos núcleos de processamento têm se tornado popular na área de
computação de alto desempenho. No entanto, o alto poder de processamento de processadores
gráficos (GPUs), está sendo cada vez mais utilizados para computação de propósito geral.
Com o desenvolvimento de arquiteturas denominadas APUs que combinam GPUs e proces-
sador multi-core, as arquiteturas heterogêneas atingem o público doméstico. Entretanto, ex-
plorar completamente esse potencial continua sendo um problema em aberto, devido à nature-
za do problema de escalonamento combinado com as ferramentas de desenvolvimento que a-
inda estão amadurecendo, e que até recentemente, limitavam-se ao uso de apenas um tipo de
processador, fato que, subutilizava o potencial de processamento destas arquiteturas. Nesse
trabalho, mostramos que a adequada coordenação de núcleos de processamento heterogêneos
pode melhorar significativamente o desempenho das aplicações, particularmente utilizando
APUs, o qual visa obter um menor impacto na transferência de dados entre dispositivos. Esta
abordagem em utilizar eficientemente esses ambientes, será feita através do particionamento
do problema entre os processadores, de acordo com sua capacidade de processamento. Para
isso, é apresentado nosso estimador de desempenho que automatiza este processo a partir do
desempenho relativo dos processadores. Com isto, coordenando a execução entre CPUs e
GPUs, e a utilização do ambiente de desenvolvimento OpenCL, alcança níveis de sincronismo
próximos do ótimo; ganhos percentuais médios em torno de 20% maiores; e eficiência média
cerca de 5 vezes melhor sobre o particionamento estático, que não considera as diferenças nas
capacidades de processamento.
Palavras-chave: Arquiteturas Heterogêneas; Computação Heterogênea; GPGPU; APUs.
OpenCL; Desempenho Relativo.
ABSTRACT
Processors with multiple cores have become popular in the area of high performance compu-
ting. However, the high processing power of graphics processors (Graphics Processing Units -
GPUs) is being increasingly used for general purpose computing. With the development of
architectures called Accelerated Processing Units (APUs) that combine GPUs and multi-core
processor, the heterogeneous architectures reach the domestic public. However, to explore
completely this potential remains an open problem, due to the nature of the problem of sche-
duling combined with the development tools that are still maturing, and that until recently we-
re limited the use of only one type of processor, the fact is, the lower use of potential proces-
sing of these architectures. On this paper, it shows the adequate coordination of heterogeneous
processing cores can improve significantly the performance of applications, using APUs par-
ticularly, which aims to get a lower impact on the data transfer between devices. This approa-
ching makes effective use of these environments done by partitioning the problem between
processors, according to its processing capacity. For this purpose, is showed our estimator of
performance that automates this process from the relative performance of processors. On this
case, coordinating the execution of CPUs and GPUs, and the use of the development envi-
ronment OpenCL, its reaches levels of synchronism next to the excellent one; an average of
gaining is around 20% higher, and an average efficiency about 5 times better on the static par-
titioning, on that does not consider the differences in processing capabilities.
Keywords: Heterogeneous Architectures, Heterogeneous Computing, GPGPU, APUs.
OpenCL; Relative Performance.
LISTA DE FIGURAS
Figura 1 – Layout da Arquitetura APU .................................................................................... 24
Figura 2 – Modelo de transferência de memória CPU + GPU versus APU ............................. 25
Figura 3 – Arquitetura da metodologia de previsão de desempenho ....................................... 27
Figura 4 – Modelo D2P2 .......................................................................................................... 29
Figura 5 – Esquema iterativo de balanceamento de carga ........................................................ 31
Figura 6 – Esquema fork-join-search ....................................................................................... 32
Figura 7 - Arquitetura dos filtros da aplicação no Anthill ........................................................ 35
Figura 8 – Arquitetura da integração do escalonamento proposto pelo autor .......................... 36
Figura 9 – Utilização do tempo de execução em diversas arquiteturas .................................... 37
Figura 10 – Ambiente de Execução OpenCL ........................................................................... 43
Figura 11 – Relação entre o Modelo de Memória OpenCL e a arquitetura GPU AMD 6970. 44
Figura 12 – Arquitetura Heterogênea proposta ........................................................................ 48
Figura 13 – Processo de particionamento entre CPU e GPU ................................................... 49
Figura 14 – Modelo aplicado ao OpenCL ................................................................................ 51
Figura 15 – Interface Timeline da ferramenta AMD APP Profiler........................................... 63
Figura 16 – Interface Session da ferramenta AMD APP Profiler ............................................ 63
LISTA DE GRÁFICOS
Gráfico 1 – Variações de desempenho para Multiplicação de Matriz ...................................... 60
Gráfico 2 – Variações de desempenho para Produto Vetorial Externo .................................... 61
Gráfico 3 - Variações de desempenho para a aplicação SAXPY ............................................. 61
Gráfico 4 - Variações de desempenho para o algoritmo Radix Sort ........................................ 62
Gráfico 5 – Resultados General Matrix Multiply ..................................................................... 66
Gráfico 6 – Resultados Vector Outer Product.......................................................................... 68
Gráfico 7 – Resultados SAXPY ................................................................................................. 69
Gráfico 8 – Resultados Radix Sort ........................................................................................... 70
Gráfico 9 – Desempenho Final do algoritmo Multiplicação de Matriz .................................... 74
Gráfico 10 – Desempenho Final do algoritmo Produto Vetorial Externo ................................ 75
Gráfico 11 – Desempenho Final do algoritmo SAXPY ........................................................... 76
Gráfico 12 – Desempenho Final do algoritmo Radix Sort ....................................................... 77
LISTA DE QUADROS
Quadro 1 – Trabalhos Relacionados ......................................................................................... 38
Quadro 2 – Arquiteturas, abordagens e ambientes utilizados nos trabalhos relacionados. ...... 39
Quadro 3 – Classificação das ferramentas do Estado da Arte .................................................. 47
Quadro 4 – Relação das aplicações analisadas ......................................................................... 53
LISTA DE TABELAS
Tabela 1 – Erro médio na previsão para o tempo de execução ................................................ 59
Tabela 2 – Desvio padrão amostral dos resultados................................................................... 65
Tabela 3 – Detalhes das variações General Matrix Multiply ................................................... 67
Tabela 4 – Detalhes das variações Vector Outer Product ........................................................ 68
Tabela 5 – Detalhes das variações SAXPY ............................................................................... 69
Tabela 6 – Detalhes das variações Radix Sort .......................................................................... 71
Tabela 7 – Avaliação: Fator de Balanço de Carga ................................................................... 72
LISTA DE SIGLAS
API Application Programming Interface – Interface de Programação de Aplicativos
APU Accelerated Processing Units – Unidade de Processamento Acelerado
CPU Central Processing Unit – Unidade Central de Processamento
CUDA Compute Unified Device Architecture
DDFCFS Demand-Driven, First-Come, First-Served
FLB Fator de balanço de carga ou razão de sincronização
GPU Graphics Processing Unit – Unidade de Processamento Gráfico
GPGPU General-Purpose computation on Graphics Processing Units
IL Intermediate Language – Linguagem Intermediária
ISA Instruction Set Architecture – Conjunto de Instruções da Arquitetura
MPI Message Passing Interface
OpenCL Open Computing Language
OpenMP Open Multi-Processing
PCIe Peripheral Component Interconnect Express
PML Parallel Markup Language – Linguagem Paralela de Marcação
PTX Parallel Thread eXecution
SPMD Single Program Multiple Data – Programas Simples para Múltiplos Dados
SUMÁRIO
1 INTRODUÇÃO ........................................................................................................ 15
1.1 Hipótese ..................................................................................................................... 16
1.2 Problema ................................................................................................................... 16
1.3 Objetivos.................................................................................................................... 17
1.3.1 Objetivo Geral ............................................................................................................ 17
1.3.2 Objetivos Específicos ................................................................................................. 17
1.4 Justificativa e contribuições .................................................................................... 17
1.5 Estrutura do Texto ................................................................................................... 18
2 ARQUITETURAS HETEROGÊNEAS ................................................................. 19
2.1 GPGPU ...................................................................................................................... 19
2.1.1 O Modelo de Programação GPU ............................................................................... 20
2.1.2 Programação GPU..................................................................................................... 21
2.2 Arquiteturas APUs ................................................................................................... 23
2.3 Escalonamento em ambientes heterogêneos .......................................................... 25
2.4 Computação heterogênea......................................................................................... 27
2.5 Considerações Finais ................................................................................................ 28
3 TRABALHOS RELACIONADOS ......................................................................... 29
3.1 D2P2 ........................................................................................................................... 29
3.2 Balanceamento de carga dinâmico ......................................................................... 30
3.3 Fork-join search ....................................................................................................... 32
3.4 Distribuição de trabalho eficiente ........................................................................... 33
3.5 Desmascarando o mito de eficiência GPU .............................................................. 33
3.6 Computação Heterogênea para Fluxos de Dados .................................................. 34
3.7 Eficiências de arquiteturas APUs ........................................................................... 36
3.8 Análise dos trabalhos relacionados ......................................................................... 37
4 DESENVOLVIMENTO .......................................................................................... 40
4.1 Open CL (Open Computing Language) .................................................................. 40
4.1.1 O padrão OpenCL ...................................................................................................... 40
4.1.2 Kernels e Modelo de Execução .................................................................................. 41
4.1.3 Ambiente de execução ................................................................................................ 42
4.1.4 Modelos de Memória .................................................................................................. 44
4.1.5 Ferramentas no Estado da Arte ................................................................................. 45
4.2 Arquitetura proposta ............................................................................................... 47
4.2.1 Processos .................................................................................................................... 47
4.2.2 Dispositivos ................................................................................................................ 50
4.3 Modelo aplicado ao OpenCL ................................................................................... 50
4.4 Executando o OpenCL ............................................................................................. 51
4.5 Considerações Finais ................................................................................................ 54
5 AVALIAÇÃO ........................................................................................................... 55
5.1 Metodologia de Avaliação ........................................................................................ 55
5.1.1 Desempenho de Algoritmos Paralelos ....................................................................... 56
5.1.2 Metodologia para definição do número de variações ................................................ 56
5.1.3 Metodologia de previsão do desempenho relativo ..................................................... 57
5.1.4 Fator de balanço de carga ou razão de sincronização (FLB) ................................... 58
5.2 Coleta dos dados ....................................................................................................... 59
5.3 Ferramenta de Análise – AMD APP Profiler ........................................................ 62
5.4 Análise Experimental ............................................................................................... 64
5.5 Resultados Experimentais ....................................................................................... 65
5.5.1 General Matrix Multiply ............................................................................................ 66
5.5.2 Vector Outer Product ................................................................................................. 67
5.5.3 SAXPY ........................................................................................................................ 69
5.5.4 Radix Sort ................................................................................................................... 70
5.6 Análise dos Resultados ............................................................................................. 71
5.6.1 Análise Qualitativa ..................................................................................................... 71
5.6.2 Análise Quantitativa ................................................................................................... 73
5.7 Considerações Finais ................................................................................................ 77
6 CONCLUSÕES ........................................................................................................ 79
6.1 Sumário dos Resultados ........................................................................................... 79
6.2 Limitações e Trabalhos Futuros ............................................................................. 81
REFERÊNCIAS ..................................................................................................................... 83
15
1 INTRODUÇÃO
Com os avanços nas arquiteturas de computadores, principalmente a popularização
dos processadores multi-core tem transformado os ambientes distribuídos em arquiteturas hie-
rárquicas e muitas vezes heterogêneas, juntamente com a utilização de GPUs (Graphics Pro-
cessing Units) como unidades de computação para propósito geral, em virtude de estas melho-
rarem significativamente o desempenho de aplicações em muitos cenários. Essas mudanças
fizeram com que plataformas equipadas com CPUs (Central Processing Units) e GPUs se
tornassem lugar comum para a computação.
Apesar dos avanços nas ferramentas de programação como OpenMP (OPENMP
ARCHITECTURE REVIEW BOARD, 2012), Nvidia CUDA SDK (NVIDIA, 2012), Open-
CL (KHRONOS GROUP, 2012), desenvolver aplicações capazes de explorar eficientemente
essas plataformas continua sendo uma tarefa difícil, pois exige grande esforço do programa-
dor que precisa conhecer detalhes da arquitetura dos processadores envolvidos e os vários ti-
pos de computação que serão executadas, impactando diretamente no desempenho das aplica-
ções (TEODORO, 2010).
Nos últimos anos muitos trabalhos afirmam que GPUs atingem aumentos substanciais
de velocidade (entre 10x e 1000x) comparados com CPUs multi-core, essas informações ge-
ralmente estão baseados nos altos picos de desempenho atingidos por GPUs (TEODORO,
2010) e/ou não consideram os custos de transmissão e sincronização entre os dispositivos
(SPAFFORD, MEREDITH, VETTER, 2010). No entanto, recentes estudos baseados nestes
resultados identificaram um aumento médio de 2,5x (LEE et al., 2011).
O desempenho relativo entre CPU e GPU pode variar de acordo com a regularidade de
acessos à memória, a qual determina o nível de paralelismo e a granularidade das tarefas do
algoritmo que está sendo executado e o impacto de sincronização (LEE et al., 2011). Todavia,
ao dividir as tarefas, sem considerar a adequação de cada uma delas aos processadores dispo-
níveis, se obtém ganhos que são proporcionais ao desempenho relativo entre GPU e CPU
(tempoGPU = tempoCPU), multiplicado pela quantidade de núcleos CPU utilizados
(TEODORO, 2010).
Portanto, para uma melhor utilização destas plataformas é preciso observar a adequa-
ção de cada uma das tarefas de computação envolvidas aos processadores disponíveis, de
forma que sejam distribuídas de maneira eficiente em ambientes heterogêneos equipados com
GPUs e CPUs multi-core.
16
Quando se considera a carga de trabalho, CPUs tem a melhor performance para apli-
cações sequenciais, pois são processadores de propósito geral possuindo poucos núcleos de
processamento e uma grande memória cache. Por outro lado, GPUs têm diversos núcleos de
processamento simplificados com uma memória cache um pouco menor, fazendo com que a-
plicações paralelas sejam mais adequadas para estas arquiteturas. Por essas razões quando a
taxa de rendimento é o foco, aplicações tendem a se adaptar melhor em GPU do que CPU
(LEE et al., 2011).
Assim, é importante observá-las para escolher, em tempo de execução, aquelas que
melhor se adequam aos processadores disponíveis. No entanto, simplesmente alocar tarefas a-
tivas adequadamente pode não ser suficiente, sendo preciso controlar as tarefas entre os pro-
cessadores, a fim de considerar as características para execução (TEODORO, 2010).
Também é importante considerar gargalo de comunicação entre CPU e GPU, atual-
mente sendo providas pelo barramento PCIe, que tem velocidades de transferência inferior
comparados com comunicação direta entre núcleos no mesmo chip. Este fator pode limitar o
potencial desses ambientes e impactar diretamente no desempenho.
No entanto novas arquiteturas heterogêneas como APU (Accelerated Processing U-
nits) ou Unidades de Processamento Acelerado (ADVANCED MICRO DEVICES, 2012a)
que consiste em dispor núcleos CPU e GPU no mesmo chip, nestas arquiteturas toda a comu-
nicação entre os processadores é feita através de em um barramento em comum. A computa-
ção heterogênea pode ser beneficiada ao utilizar essa abordagem, pois sugere que alguns dos
problemas de comunicação sejam contornados.
1.1 Hipótese
Tarefas podem ter padrões de desempenho que variam de acordo com a arquitetura
computacional onde é executada. Arquiteturas heterogêneas podem obter vantagens, se as ta-
refas forem classificadas e alocadas de acordo com suas características de desempenho espe-
cíficas, em relação aos processadores disponíveis.
1.2 Problema
Nesta perspectiva configura-se como problema: como realizar o escalonamento de ta-
refas em ambientes heterogêneos, considerando as características das tarefas e a arquitetura
dos processadores (CPU e GPU), buscando aperfeiçoar métricas de speedup e eficiência.
17
O problema de escalonar aplicações em ambientes heterogêneos é difícil de ser resol-
vido por ao menos três razões: (i) em termos gerais é amplamente conhecido como NP-
completo; (ii) as tarefas relacionadas à execução da aplicação são criadas em tempo de execu-
ção, assim, qualquer escalonamento estático é inviável; (iii) estimar o tempo de execução de
aplicações/tarefas é um problema em aberto (TEODORO, 2010 apud Fernandez, 1989;
Maheswaran et al., 1999; Fahringer, Zima, 1993; Kerbyson et al., 2001; Vrsalovic et al.,
1988).
1.3 Objetivos
Acredita-se que seja possível obter melhor desempenho em ambientes heterogêneos ao
considerar as características das tarefas e dos módulos de processamento envolvidos, de forma
que todos os recursos disponíveis sejam utilizados de maneira eficiente.
1.3.1 Objetivo Geral
O objetivo principal do trabalho é elaborar um estudo sobre computação heterogênea e
apresentar uma abordagem de distribuição de tarefas entre CPUs e GPUs através de processa-
dores heterogêneos (APU), visando obter maior aproveitamento da arquitetura como um todo,
utilizando aplicações paralelas como benchmarks para validação dos resultados.
1.3.2 Objetivos Específicos
Explorar a interface OpenCL que atualmente é o padrão para desenvolvimento em ar-
quiteturas heterogêneas. Estudar as arquiteturas heterogêneas para computação de propósitos
gerais. Pesquisar as formas de escalonamento de tarefas para ambientes de computação hete-
rogênea CPU-GPU. Apresentar os resultados obtidos com a finalidade de contribuir para os
avanços científicos nesta área.
1.4 Justificativa e contribuições
Grande parte da experiência de computação está conectada ao software, no entanto, os
desenvolvedores de software têm sido limitados pela natureza independente com a qual as
CPUs e GPUs processam a informação (ALVES, 2011). A computação heterogênea abre no-
18
vos desafios e oportunidades em áreas como processamento paralelo, projeto de algoritmos
para aplicações concorrentes, particionamento e mapeamento das tarefas paralelas
(MAHESHWAR, 1996).
A programação multi-GPU herdou alguns dos problemas conhecidos na programação
paralela convencional e agravou o problema da complexidade em adequar as tarefas para as
diversas arquiteturas de processadores envolvidos. Fazendo com que o desenvolvimento efici-
ente de aplicações para estas arquiteturas seja diretamente ligado à forma como as tarefas são
distribuídas entre os processadores (ACOSTA et al., 2011).
A contribuição deste trabalho está associada à investigação do escalonamento de tare-
fas em ambientes heterogêneos integrados (APUs) considerando as características das tarefas
para os processadores envolvidos e as variações no tamanho do problema.
Também se apresenta como continuidade de um de nossos trabalhos anteriores que foi
apresentado à comunidade científica regional (KAUER, SIQUEIRA, 2012).
1.5 Estrutura do Texto
O restante deste trabalho foi dividido em 5 capítulos, organizados da seguinte forma:
Capítulo 2 [Arquiteturas Heterogêneas]: descreve as arquiteturas heterogêneas com
foco em ambientes muiti-CPU/GPU juntamente com o conceitos de GPGPU, computação he-
terogênea e escalonamento em ambientes heterogêneos.
Capítulo 3 [Trabalhos Relacionados]: descreve o estado das seguintes áreas, com as
quais este trabalho tem sobreposição: computação em aceleradores e escalonamento em ambi-
entes heterogêneos.
Capítulo 4 [Desenvolvimento]: descreve o ambiente de desenvolvimento OpenCL jun-
tamente com o desenvolvimento da arquitetura proposta.
Capítulo 5 [Avaliação]: discute a metodologia de avaliação juntamente com a avalia-
ção qualitativa e quantitativa do trabalho proposto.
Capítulo 6 [Conclusões]: discute alguns dos principais resultados e limitações deste
trabalho e, sugere direções de trabalhos futuros.
19
2 ARQUITETURAS HETEROGÊNEAS
Arquiteturas heterogêneas têm ganhado bastante espaço na área da computação de alto
desempenho, isso se deve principalmente à popularização de processadores gráficos cada vez
mais eficientes, que apesar de disponibilizarem frequências de ciclo relativamente inferiores
aos processadores multi-core atuais, sua grande quantidade de núcleos simples podem execu-
tar centenas de cálculos ao mesmo tempo, fazendo com que, em alguns casos, possam apre-
sentar desempenho muito superior aos processadores tradicionais e frequentemente consu-
mindo uma menor quantidade de energia.
As primeiras arquiteturas heterogêneas surgiram em ambientes científicos
(EKMECIÉ, TARTALJA, MILUTINOVIÉ, 1995), posteriormente tornaram-se populares em
clusters de alto desempenho (TOP500.ORG, 2012). Atualmente, arquiteturas heterogêneas
como a Intel MIC (INTEL, 2012) e processadores heterogêneos APUs (ADVANCED
MICRO DEVICES, 2012a) fizeram com que arquiteturas heterogêneas atingissem o público
doméstico.
O restante do capítulo está dividido na seguinte forma: na seção 2.1 serão abordados
os principais conceitos sobre GPGPU e programação GPU em geral; na seção 2.2 serão ex-
planadas as arquiteturas APUs abordadas neste trabalho; na seção 2.3 será apresentada uma
visão geral da literatura estudada sobre escalonamento em ambientes heterogêneos; a seção
2.4 serão abordados os conceitos de computação heterogênea no contexto deste trabalho; e fi-
nalmente na seção 2.5 serão apresentadas as considerações finais do capítulo.
2.1 GPGPU
GPGPU (General-Purpose computation on Graphics Processing Units) é o conceito
utilizado para designar a utilização de GPUs para computação de propósito geral. Inicialmen-
te, GPGPU estava limitado às linguagens de programação proprietárias tais como CUDA
(NVIDIA, 2012) e AMD FireStream (ADVANCED MICRO DEVICES, 2012b). Posterior-
mente, OpenCL (KHRONOS GROUP, 2012) surgiu como um padrão para o desenvolvimen-
to de aplicações utilizando recursos de arquiteturas heterogêneas de diversos fabricantes.
Owens et al. (2008) desenvolveram um dos primeiros trabalhos detalhados sobre
GPGPU, apresentando GPUs como alternativa de unidades de processamento de alto desem-
penho do futuro. Abordando desde a arquitetura de hardware até o modelo de programação
20
GPU e apresentando aplicações práticas onde foi obtido desempenho significativo em relação
a aplicações em CPUs tradicionais.
A arquitetura GPU é projetada para uma determinada classe de aplicações que tenham
essencialmente as seguintes características (OWENS et al., 2008):
a) Grandes requisitos computacionais;
b) Processamento de dados com alto nível de paralelismo;
c) Rendimento seja mais importante que a latência.
Essas características combinadas são identificadas especialmente no processamento
gráfico, onde os pixels podem ser processados independentemente juntamente com o fato de
que o sistema visual humano opera em escala milhares de vezes mais lento do que os atuais
processadores.
2.1.1 O Modelo de Programação GPU
A arquitetura GPU segue o modelo de programação SPMD (Single Program Multiple
Data), que consiste em processar muitos elementos em paralelo utilizando o mesmo progra-
ma. Estes elementos compartilham uma memória global para leitura e escrita. Este modelo de
programação é beneficiado pelo fato das GPUs terem poucas unidades de controle de fluxo,
por outro lado, esta característica faz com que desvios de execução resultem em altos custos
de programação (OWENS et al., 2008). Isso pode ser contornado agrupando os elementos em
blocos, e posteriormente estes blocos são processados em paralelo. Ainda assim, isso requer
muito esforço do programador, que deve estar atento a estes detalhes, de modo que o todo o
potencial do hardware seja utilizado.
Este modelo de programação é adequado para os programas lineares, onde muitos e-
lementos podem ser processados independentemente a partir do mesmo código. Esta caracte-
rística de programação é muito poderosa por várias razões:
a) Permite que o hardware explore o paralelismo de dados explicitamente;
b) Estabelece programação de propósito geral individual para cada elemento, ofere-
cendo restrições de comunicação entre os elementos e outros programas;
c) A facilidade de acesso direto às unidades programáveis elimina grande parte da
complexidade enfrentada pelos programadores, juntamente com uma linguagem de
programação familiar que é mais simples e mais fácil de depurar.
Uma das vantagens desta abordagem é a possibilidade de controlar o fluxo por thread.
Os elementos são agrupados em blocos, e blocos são processados em paralelo. O tamanho do
21
bloco é conhecido como granularidade da tarefa. (OWENS et al., 2008). O resultado é um
modelo de programação que permite aos desenvolvedores aproveitar todo o potencial do
hardware da GPU, permitindo o desenvolvimento de aplicativos mais complexos.
As atuais GPUs e derivados tem como objetivo o melhor custo-benefício eficiên-
cia/consumo de energia, para isso, são equipadas com memória com grande capacidade de
transferência, geralmente GDDR5 que tem como característica a alta latência. Comparando o
núcleo destas arquiteturas com CPUs, o design AMD tem 24 cores enquanto que o design
NVIDIA tem 16 (GASTER et al., 2011). A memória local é alocada pelo grupo de trabalho,
permitindo uma grande quantidade de concorrência. A utilização deste modelo reduz, signifi-
cativamente, o consumo de energia comparado às memórias caches, devido ao fato de não
precisar ser gerenciadas pelo hardware.
2.1.1.1 CUDA (Compute Unified Device Architecture)
CUDA é uma interface de programação criada com intuito de facilitar a utilização de
placas gráficas para computação de propósito de geral (NVIDIA, 2012). Essa interface foi de-
senvolvida como uma extensão da linguagem de programação C, incluindo diversos detalhes
necessários para a exploração eficiente dessas placas.
A arquitetura das placas Nvidia é composta por um conjunto de multiprocessadores
com múltiplos núcleos de processamento. A comunicação entre multiprocessadores, por sua
vez, é feita através da memória global do dispositivo. A visão da GPU exportada por CUDA é
a de um dispositivo adequado para execução de aplicações com paralelismo de dados, capaz
de executar um grande número de threads concorrentemente.
Existem também múltiplos níveis de acesso à memória, com custos de acesso diferen-
tes, que são gerenciados pelo programador. As threads são organizadas em blocos, que, por
sua vez, são agrupados em grids. O código executado na GPU recebe o nome de kernel e deve
considerar a partição do processamento entre as threads, conforme o identificador das mes-
mas. Threads do mesmo bloco compartilham dados através da memória compartilhada e po-
dem ser sincronizadas utilizando primitivas específicas do CUDA (TEODORO, 2010).
2.1.2 Programação GPU
A GPU é projetada para uma determinada classe de aplicações com alto nível de para-
lelismo e rendimento com baixa latência. Há alguns anos atrás, a GPU era um processador de
22
função fixa, construído em torno do pipeline de gráficos. Desde aquela época, a GPU evoluiu
para um poderoso processador programável, tanto a interface de programação de aplicativo
(APIs) quanto hardware cada vez mais focando para os aspectos programáveis da GPU. O re-
sultado é um processador de grande capacidade de processamento.
O desafio para os fabricantes e pesquisadores tem sido a de encontrar o equilíbrio en-
tre baixo nível de acesso ao hardware para permitir desempenho nas linguagens de programa-
ção de alto nível e ferramentas que permitem flexibilidade programador e produtividade
(OWENS et al., 2008).
Atualmente, três dos cinco maiores supercomputadores mais rápidos do mundo em-
pregam GPUs (TOP500.ORG, 2012). É importante observar que os supercomputadores equi-
pados com GPUs atingem apenas 50% do seu desempenho de pico teórico, enquanto os su-
percomputadores sem GPUs atingem 78% do pico teórico. Isto demonstra que há certos as-
pectos da GPUs que limitam o desempenho para o Linpack, benchmark utilizado para classi-
ficar os supercomputadores na Top500 (DAGA, AJI, FENG, 2011).
Conforme foi argumentado por Teodoro (2010), “a dificuldade em se explorar efeti-
vamente esses ambientes está intimamente relacionada pelo menos a dois fatores”:
a) a dificuldade de desenvolver aplicações que façam uso eficiente do hardware dis-
ponível;
b) e a ineficiência no escalonamento de aplicações, que podem ter características que
as tornam mais adequadas para processadores com arquiteturas distintas.
Dessa forma, não considerar a adequação de cada tarefa aos dispositivos de computa-
ção existentes pode fazer com que os processadores passem grande parte do tempo de execu-
ção processando tarefas para as quais eles são inadequados.
Em sistemas acelerados por GPUs, as GPUs não só proporcionam um alto desempe-
nho de pico, mas também reduzem o consumo de energia consideravelmente. Entretanto, de-
vido à sua limitação arquitetônica, o desempenho está relacionado com a intensidade de apli-
cação do cálculo, paralelismo e modelo de acesso à memória, etc. Portanto, a distribuição de
trabalho razoável entre CPUs e GPUs é uma forma eficaz para explorar melhor os sistemas
heterogêneos CPU-GPU (WANG, REN, 2010).
Ao longo dos últimos anos, a GPU evoluiu de um processador com função fixa em um
processador paralelo programável de propósito geral. Consequentemente, a arquitetura da
GPU evoluiu em uma direção diferente do que a CPU. As principais formas de paralelismo
encontradas em uma arquitetura são de tempo e a de recursos. Para executar uma tarefa para-
lela, a CPU utiliza paralelismo no tempo, aplicando todos os recursos em cada tarefa por um
23
determinado tempo, no entanto, a GPU divide os recursos do processador em várias tarefas
simultaneamente, de modo que o trabalho é dividido no espaço, e não no tempo. Desta forma,
o ganho obtido no desempenho é fruto da quantidade de processadores que trabalham em con-
junto (DE ROSE, NAVAUX, 2003).
No entanto, a principal desvantagem do paralelismo utilizando GPU é o balanceamen-
to de carga, onde o desempenho é diretamente dependente da tarefa mais lenta. Todavia, a
vantagem é um processador altamente paralelo de alto desempenho.
2.2 Arquiteturas APUs
GPUs demonstraram que suas capacidades de computação de propósito geral são ade-
quadas para aplicações de dados intensivos. No entanto, o gargalo de comunicação para trans-
ferência de dados entre a GPU e CPU levou ao projeto de Unidade de Processamento Acele-
rado da AMD (APU), que combina a CPU e GPU em um único chip.
A tecnologia combina núcleos de propósito gerais e processadores vetoriais escalares
em um único molde de silício, formando um processador de computação heterogênea. Esse
fato pode ajudar a melhorar o desempenho geral dos gráficos. O desempenho gráfico nestas
arquiteturas pode ser comparado com GPUs discretas (offboard). Uma segunda vantagem é a
possibilidade de combinar mais GPUs com o processador gráfico da APU utilizando a tecno-
logia chamada AMD Dual Graphics (CASE, 2011). Entretanto, jogos mais antigos podem não
obter acesso aos recursos de múltiplas GPUs e as placas gráficas adicionais devem ser compa-
tíveis com a APU instalada.
No entanto, placas como a AMD Radeon HD 6850 e superior, não se beneficiam com
esta tecnologia e o processador gráfico da APU é desabilitado, permitindo que a GPU mais e-
ficiente assuma as tarefas gráficas. Mesmo assim, a combinação GPU discreta e APU pode
oferecer um aumento de desempenho considerável, com um investimento de baixo custo
(CASE, 2011).
Essa mudança para um ambiente fortemente integrado implica diretamente na maneira
de desenvolver os algoritmos, explorar seus recursos computacionais e compartilhamento de
memória, fazendo com que estas arquiteturas tenham um novo nível de poder computacional
para o público em massa que antes seria limitado a processadores multi-core.
Grande parte das aplicações que utilizam GPUs são limitadas pelo gargalo de comuni-
cação entre CPU e GPU, no entanto é possível que estas arquiteturas nativamente heterogê-
neas obtenham certa vantagem em relação a programação multi-GPU tradicional, devido ao
24
fato da baixa latência das cargas de trabalho para GPUs que antes eram limitadas pelo barra-
mento PCIe.
O aspecto fundamental a ser observado é que os núcleos de CPU e GPU estão ligados
à memória do sistema através do mesmo barramento de alta velocidade, juntamente com um
controlador de memória. Este artefato arquitetônico permite as arquiteturas APUs eliminar a
restrição de desempenho existente em uma GPU discreta (DAGA, AJI, FENG, 2011).
A Figura 1 mostra um diagrama de blocos desta arquitetura. Além de núcleos de pro-
cessamento, APUs dispõem de um controlador de memória, entrada e saída, decodificador de
vídeo e interfaces de barramento, todos integrados no mesmo chip.
Figura 1 – Layout da Arquitetura APU
Fonte: traduzido de Daga, Aji, Feng, 2011.
Esta característica se deve à forma como a memória é compartilhada entre ambos os
dispositivos, que embora compartilhem um barramento comum para a memória do sistema,
estas arquiteturas dividem a memória do sistema em duas partes: uma que é visível e gerenci-
ada pelo sistema operacional e acessada pelos núcleos CPU e a outra que é gerenciado pelo
driver de vídeo e acessada pelos núcleos GPU (DAGA, AJI, FENG, 2011). No entanto isto
implica na redução da banda de memória da GPU quando comparada com outras GPUs dis-
cretas que utilizam a própria memória GDDR5.
Todavia, ao contrário de GPUs tradicionais, onde essas transferências de dados da
memória do sistema para a memória do dispositivo ocorriam através do barramento PCIe, as
transferências de dados ocorrem através de uma operação simples de cópia de memória
(memcopy), como pode ser observado na Figura 2.
25
Figura 2 – Modelo de transferência de memória CPU + GPU versus APU
Fonte: traduzido de Daga, Aji, Feng, 2011.
Por outro lado, é provável que uma grande quantidade de algoritmos que são ineficien-
tes quando aplicados em GPUs tradicionais que contenham grandes partes seriais ou que a
comunicação seja o gargalo de desempenho, obtenham grande desempenho quando aplicados
a estas arquiteturas (DAGA, AJI, FENG, 2011).
2.3 Escalonamento em ambientes heterogêneos
Grande parte dos trabalhos sobre escalonamento em ambientes multi-CPU/GPU está
disponível em artigos científicos de trabalhos recentes. A computação heterogênea e o escalo-
namento de tarefas para esses ambientes tem se tornado o foco de muitos estudos, todavia as
limitações das arquiteturas e a disponibilidade de bibliotecas específicas pelos fabricantes tem
impedido que muitos das técnicas de escalonamento fossem aplicados nestes ambientes.
No entanto, segundo Teodoro (2010) “as tarefas de computação têm padrões de de-
sempenho que se diferenciam entre as arquiteturas de processadores heterogêneos”. Isso im-
plica no fato de além das tarefas terem características de execução próprias, a forma de exe-
cução destas pode variar conforme o processador que a executa.
Estas diferenças podem ser observadas quando as mesmas tarefas são alocadas exclu-
sivamente para CPU ou GPUs, nestes casos, fazendo com que ocorram grandes variações no
tempo de execução conforme os parâmetros de entrada são variados.
Um fator importante a ser considerado é que apesar da GPU apresentar desempenho
em muitos casos superior aos da CPU, existem situações nas quais esses dois processadores
têm desempenho similares (TEODORO, 2010; LEE et al., 2011), fazendo com que a utiliza-
ção exclusiva da GPU não seja a melhor estratégia (TEODORO, 2010).
26
Teodoro (2010) apud Luk et al., (2009) apresenta a interface Qilin como um sistema
para desenvolvimento de aplicações em ambientes heterogêneos, que oferece uma interface
com operações paralelizáveis, as quais podem utilizar CPU e GPU conjuntamente. Uma das
vantagens desse sistema é a possibilidade de alocar recursos automaticamente, fazendo o par-
ticionamento de tarefas para CPU e GPU baseado em execuções anteriores e utilizando os da-
dos das execuções como aprendizagem para melhorar o desempenho das tarefas em novas e-
xecuções.
O processo escalonamento em ambientes heterogêneos tem sido foco de pesquisa
principalmente na área de sistemas distribuídos (TEODORO 2010 apud Feitelson et al. 1997;
Ahmad 1995). Atualmente, com a evolução do hardware, arquiteturas nativamente heterogê-
neas tem alcançado o público doméstico. Fazendo com que arquiteturas heterogêneas passas-
sem de ambientes distribuídos proprietários para um lugar comum para a computação.
A maioria destes trabalhos utiliza métodos iterativos entre os nodos distribuídos, os
quais são equipados com CPUs multi-core e GPUs, sendo que, o que diferencia entre estes
trabalhos muitas vezes é a forma como os nodos são sincronizados, como foi desenvolvido
nos trabalhos de Taifi, Khreishah, Shi (2011) e Ou, Chen, Lai (2011). Nestes trabalhos os da-
dos são processados quase que exclusivamente nas GPUs, enquanto que tarefas de sincroniza-
ção e comunicação entre os nodos são executadas pela CPU, o problema nestas abordagens é
a subutilização da capacidade de processamento das CPUs (TEODORO, 2010).
Outra maneira de se obter o escalonamento eficiente está na forma como as tarefas se-
rão distribuídas entre os processadores. Nestes trabalhos pode-se citar Acosta et al. (2011) que
propõe iterações para que a distribuição da carga seja dinâmica. As iterações acontecem até
que ocorra equilíbrio entre os processadores mais rápidos e os mais lentos.
Todavia, também é possível considerar os desempenhos relativos entre os processado-
res antes da execução como foi feito nos trabalhos de Spafford, Meredith, Vetter (2010) e Te-
odoro (2010). Neste caso, a divisão do trabalho ocorre após uma etapa de treinamento que po-
de ser a execução individual de cada dispositivo (TEODORO, 2010) ou a utilização de um
benchmark genérico (SPAFFORD, MEREDITH, VETTER, 2010).
Assim, os desempenhos relativos de cada um dos dispositivos são armazenados em
uma base de dados que alimenta um módulo de previsão, juntamente com os parâmetros de
entrada para obter a melhor forma de escalonamento das tarefas. Este processo pode ser ob-
servado na Figura 3, primeiramente, a fase de treinamento executa a carga de trabalho em
ambos os dispositivos e posteriormente, na fase de previsão, o módulo de previsão faz a con-
sulta à base de dados.
27
Figura 3 – Arquitetura da metodologia de previsão de desempenho
Fonte: Teodoro, 2010.
2.4 Computação heterogênea
Ao realizar o escalonamento entre CPUs, GPUs e outros dispositivos se obtêm o con-
ceito de computação heterogênea, onde diversos tipos de processadores executam cooperati-
vamente uma mesma computação. Esta definição surgiu com o desenvolvimento de sistemas
distribuídos, clusters e grids de computação, e mais recentemente quando GPUs se tornaram
populares para o processamento gráfico em computadores pessoais e posteriormente com o
desenvolvimento de pesquisas na área da GPGPU.
A computação heterogênea também adicionou vantagens em muitos aspectos, por e-
xemplo, permitindo que a melhor arquitetura execute as tarefas fazendo melhor uso da arqui-
tetura heterogênea e contribuindo para a solução de muitos problemas que envolvem variação
das tarefas (GASTER et al., 2011).
Inicialmente, devem-se avaliar os diferentes recursos de hardware destas arquiteturas e
suas aplicações para computação. O núcleo da CPU é projetado para uma ampla gama de a-
plicações, principalmente computação sequencial. Para melhorar o desempenho, o núcleo da
CPU utiliza o paralelismo em nível de instrução (também conhecido como paralelismo de
tempo), permitindo que mais do que uma operação seja executada por ciclo. Isto implica que
28
o rendimento da CPU é diretamente proporcional ao número de núcleos utilizados (LEE et al.,
2011).
Por outro lado, GPU obtém alto desempenho de uma forma simples: uma unidade de
controle coordena a execução em vários processadores que executam o mesmo código. Isto
faz com que a capacidade de processamento relativa seja superior em CPUs quando compara-
das com núcleos CPU (LEE et al., 2011). Embora a largura de banda da GPUs seja aproxima-
damente 4,7x maior que CPU, a capacidade de bytes/flop é aproximadamente 1,6x menor.
Uma diferença que deve ser considerada são as operações de sincronização: enquanto
CPUs podem ser sincronizadas facilmente, em GPUs estas operações não são complexas. A
utilização da memória cache também varia muito entre estas arquiteturas, em GPUs ela é mui-
to pequena, isso implica no fato desta não poder ser utilizada com a mesma facilidade que é
utilizada em CPUs (LEE et al., 2011).
2.5 Considerações Finais
Neste capítulo, foram apresentados os principais conceitos de arquiteturas heterogê-
neas CPU/GPU e computação heterogênea que estão diretamente relacionados a um dos obje-
tivos do trabalho proposto: estudar as arquiteturas multi-CPU/GPU. Também foram explica-
dos os principais aspectos destas arquiteturas juntamente com um breve histórico da evolução
da programação desde os modelos de programação GPU até escalonamento de tarefas em am-
bientes heterogêneos.
Também foram descritas as arquiteturas APUs que são o foco deste trabalho juntamen-
te com suas principais características e dos processadores que compõem estas arquiteturas.
Além disso, foram discutidas algumas abordagens de escalonamento disponíveis na literatura
para estes ambientes e algumas definições que devem ser observadas ao distribuir as tarefas.
No próximo capítulo serão apresentados trabalhos que se utilizaram das técnicas, mo-
delos e ferramentas descritos nesta seção. No capítulo 4 será descrita a solução proposta utili-
zando o ambiente de desenvolvimento OpenCL.
3 TRABALHOS RELACIONAD
Esse capítulo apresenta alguns dos principais trabalhos relacionados, que são divididos
em duas áreas com as quais existe sobreposição: computaçã
to em ambientes heterogêneos.
3.1 D2P2
O uso de multiplexação em duas camadas chamado de
Processing (D2P2) (TAIFI, KHREISHAH
lidade para sistemas que usa
CUDA/CUBLAS. Cada GPU é gerenciada por um núcleo CPU do processador
todos os nodos de processamento independente (CPU + GPU) estão interconectados por um
conjunto de switches redundantes
gura 4. Uma aplicação central faz o controle da comunicação e configuração dos nodos
te um nodo master que contém o programa principal e a sequência de execução e é respons
vel pela distribuição das tarefas e organização dos resultados dos outros nodos, que executam
a computação e enviam os resultados ao nodo
Fonte: Taifi e Shi
Cada nodo procura um
for encontrado, a computação é realizada pela CPU. Permitindo assim, algumas vantagens
como: balanceamento de carga automático, sem necessidade de programação explícita; Fac
lidade de programação, permitindo a transformação automática de programas sequenciais em
TRABALHOS RELACIONAD OS
Esse capítulo apresenta alguns dos principais trabalhos relacionados, que são divididos
em duas áreas com as quais existe sobreposição: computação em aceleradores e escaloname
to em ambientes heterogêneos.
O uso de multiplexação em duas camadas chamado de Deeply Decoupled Parallel
(TAIFI, KHREISHAH, SHI, 2011) permite alto desempenho e disponib
lidade para sistemas que usam processadores multi-core e GPUs, utilizando biblioteca
CUDA/CUBLAS. Cada GPU é gerenciada por um núcleo CPU do processador
todos os nodos de processamento independente (CPU + GPU) estão interconectados por um
conjunto de switches redundantes formando um anel lógico como pode ser observado na F
. Uma aplicação central faz o controle da comunicação e configuração dos nodos
que contém o programa principal e a sequência de execução e é respons
s tarefas e organização dos resultados dos outros nodos, que executam
a computação e enviam os resultados ao nodo master.
Figura 4 – Modelo D2P2
Fonte: Taifi e Shi, 2011.
a um kernel GPU disponível para realizar a computação. Se este não
for encontrado, a computação é realizada pela CPU. Permitindo assim, algumas vantagens
como: balanceamento de carga automático, sem necessidade de programação explícita; Fac
amação, permitindo a transformação automática de programas sequenciais em
29
Esse capítulo apresenta alguns dos principais trabalhos relacionados, que são divididos
o em aceleradores e escalonamen-
Deeply Decoupled Parallel
permite alto desempenho e disponibi-
e GPUs, utilizando biblioteca
CUDA/CUBLAS. Cada GPU é gerenciada por um núcleo CPU do processador multi-core e
todos os nodos de processamento independente (CPU + GPU) estão interconectados por um
como pode ser observado na Fi-
. Uma aplicação central faz o controle da comunicação e configuração dos nodos. Exis-
que contém o programa principal e a sequência de execução e é responsá-
s tarefas e organização dos resultados dos outros nodos, que executam
GPU disponível para realizar a computação. Se este não
for encontrado, a computação é realizada pela CPU. Permitindo assim, algumas vantagens
como: balanceamento de carga automático, sem necessidade de programação explícita; Faci-
amação, permitindo a transformação automática de programas sequenciais em
30
programas paralelos utilizando técnicas de PML (Parallel Markup Language); Facilidade de
otimização de desempenho: granularidade pode ser ajustada manualmente ou automaticamen-
te, sem recompilação; Tolerância a falhas: falhas de processamento são identificadas e contro-
ladas pelo nodo mestre através de um protocolo de check-points não-bloqueantes. Este mode-
lo permite alta disponibilidade de recursos para aplicações paralelas, consumido o mínimo de
recursos redundantes para controle de falhas.
Para atingir o desempenho ótimo é necessário encontrar a melhor granularidade de
processamento. Este procedimento ocorre em duas etapas: (i) Encontrar a melhor distribuição
de modo que o número máximo de tarefas paralelas que podem ser executadas ao mesmo
tempo, sem exceder a largura de banda da rede. (ii) Encontrar o tamanho de grão ótimo pro-
cessamento que pode ser obtido quando se minimiza o tempo de sincronização geral, onde to-
das as tarefas distribuídas terminam com a menor diferença de tempo, este processo pode ser
automatizado utilizando um gerador de código PML.
Em média, o aumento de desempenho é de 29% quando combinados CPUs e GPUs.
No entanto, esse valor pode variar conforme a granularidade da computação executada. A
granularidade ideal garante sobrecarga de sincronização mínimo pela sobreposição de tempos
de computação e comunicação. O melhor desempenho foi obtido utilizando três GPUs, pois
mais GPUs produzem resultados piores devido à contenção de memória e custos de sincroni-
zação.
3.2 Balanceamento de carga dinâmico
Acosta et al (2011) propõe uma biblioteca de balanceamento dinâmico de carga que
permite que o código paralelo seja adaptado para sistemas heterogêneos utilizando alocação
de recursos CUDA. O algoritmo visa evitar desequilíbrios de carga entre as threads da GPU,
facilitando a tarefa do programador de adaptar código paralelo desenvolvido para sistemas
homogêneos para os heterogêneos. A biblioteca foi desenvolvida para proporcionar o mínimo
de mudança no código de programas existentes, minimizando assim intrusão do código.
Os resultados dos autores mostram que os benefícios obtidos através desta abordagem
implicam em reduções significativas de tempo de programação. O nível de eficiência obtidos,
considerando-se a intrusão código mínimo, faz com que esta biblioteca seja uma ferramenta
útil no contexto de plataformas heterogêneas.
Para resolver as diferenças de tempo na execução do código paralelo, é utilizado um
esquema iterativo, onde uma operação de cálculo é realizada para cada iteração. Cada proces-
31
sador irá executar cálculos de acordo com o tamanho da tarefa alocada. Após, uma operação
de comunicação coletiva é realizada onde todos os processadores podem sincronizar os dados
antes de prosseguir para a próxima iteração.
A Figura 5 mostra como seria as iterações na teoria. À esquerda, se não fosse conside-
rado o balanceamento de carga; e à direita utilizando a biblioteca de balanceamento de carga
proposta pelos autores.
Figura 5 – Esquema iterativo de balanceamento de carga
Fonte: traduzido de Acosta et al., 2011.
Este esquema iterativo aparece em muitos algoritmos paralelos, como multiplicação de
matriz jacobiana, programação dinâmica, caminho mais curto, etc. Nestes casos, ao imple-
mentar distribuição de tarefas homogêneas, onde o tamanho do problema é o mesmo atribuído
a cada processador, resultará, no tempo mínimo, que diretamente dependente do processador
mais lento, fazendo com que outros processadores fiquem ociosos durante cada iteração.
A biblioteca desenvolvida permite o balanceamento dinâmico com a introdução de a-
penas duas chamadas. A chamada é introduzida no início e no final da seção a ser equilibrada,
de modo que cada processador possa saber em tempo de execução quanto tempo será utiliza-
do para executar a tarefa atribuída. O balanceamento de carga é obtido comparando o tempo
de execução real de tarefas para cada processador com a redistribuição de tarefas subsequen-
tes (ACOSTA et al., 2011).
Deste modo, a quantidade de tarefas definidas para cada processador é proporcional a
sua capacidade de processamento. No entanto, o menor desempenho foi obtido quando se au-
menta a quantidade de GPUs envolvidas no processamento, isso se deve a grande quantidade
de iterações e operações de sincronização e comunicação entre os processadores.
32
3.3 Fork-join search
O método fork-join search (OU, CHEN, LAI, 2011), consiste em dividir uma tarefa
principal em sub-tarefas, processá-las individualmente e sincronizar os resultados. O ambiente
consiste em nodos heterogêneos que utilizam CPUs e GPUs e as tarefas são distribuídas de
maneira apropriada para alcançar o equilíbrio de carga a partir do número de tarefas concluí-
das em cada iteração que será atualizada dinamicamente.
Neste modelo de arquitetura existem três tipos de nodos, como pode ser observado na
Figura 6: Gerenciador (MN), responsável pelo andamento da tarefa e por enviar comandos de
controle ao escalonador; Escalonador (SN): responsável por controlar as filas e distribuir as
sub-tarefas aos nodos de trabalho (CN) que executam a computação.
Figura 6 – Esquema fork-join-search
Fonte: Ou, Chen, Lai, 2011.
Em cada nodo, as GPUs são usadas para o processamento de alto desempenho e os
CPUs são usados para receber a tarefa e enviar o resultado. O escalonador calcula a capacida-
de de computação de cada nó e determina quantas sub-tarefas devem ser enviadas para os nós
de computação em cada ciclo. No Escalonador, todas as sub-tarefas são colocadas em uma fi-
la global. Uma fila auxiliar controla as tarefas que foram alocadas, mas que os resultados do
nodo não retornaram. Então, n filas armazenam as tarefas atribuídas a n nodos.
A capacidade de computação de cada nodo é obtida pelo número de resultados recebi-
dos. As sub-tarefas são alocadas para os nodos de maneira dinâmica e as execuções são con-
troladas por ciclos, aumentando a precisão a cada ciclo de execução. O escalonador envia
número apropriado de sub-tarefas para cada nodo de computação em cada ciclo, fazendo com
que nenhum nodo fique ocioso. Se após alguns ciclos não for obtido o resultado, a sub-tarefa
33
é considerada perdida e é realocada no próximo ciclo. Os resultados mostram um aproveita-
mento de 98% da capacidade de processamento utilizando quatro nodos (OU, CHEN, LAI,
2011).
3.4 Distribuição de trabalho eficiente
Considerando o consumo energético, Wang, Ren (2010) propõem um algoritmo de
distribuição de trabalho em sistemas heterogêneos entre CPUs e GPUs. O método de balance-
amento dinâmico é escalável baseado na frequência do processador visando minimizar o con-
sumo de energia.
O resultado revela a diferença principal de otimização entre sistemas heterogêneos e
homogêneos. Em sistemas homogêneos, o consumo mínimo de energia é obtido quando se
obtém a carga de trabalho distribuída igualmente entre os processadores, independente do ta-
manho da tarefa. Enquanto que para os sistemas heterogêneos, diferentes processadores têm
desempenho diferentes e eficiências energéticas diferentes para uma determinada aplicação.
O algoritmo percorre todas as combinações possíveis de diferentes níveis de execução
de CPU e GPU, buscando encontrar a combinação que obtenha o menor consumo de energia e
com o menor tempo de execução. Os resultados mostram que com a distribuição de trabalho
entre CPU e GPU, foi obtida redução de 14% no consumo de energia comparados com mape-
amentos estáticos típicos.
Assim, a execução eficiente de aplicações em ambientes heterogêneos continua sendo
um dos grandes desafios em computação de alto desempenho. Enquanto os avanços em arqui-
tetura de computadores têm aumentado o pico de desempenho dos processadores, somente
uma fração, muitas vezes pequena, desse potencial de computação é utilizado na prática em
diversas aplicações reais (WANG, REN, 2010).
3.5 Desmascarando o mito de eficiência GPU
Lee et al (2011) realizaram uma análise de muitos trabalhos e estudos de diversos au-
tores que afirmam que GPUs produzem de 10x a 1000x mais desempenho comparados com
CPUs multi-core. Neste trabalho os autores obtiveram um aumento médio de 2,5 vezes e dis-
cutem técnicas de otimização do código para arquiteturas GPU e CPU que contribuíram para
esta diferença de desempenho entre estas arquiteturas.
34
Também foram relacionadas algumas características de computação que têm desem-
penhos diretamente relacionados à forma como são processados, verificando que em alguns
casos GPUs são mais eficientes que CPUs e vice-versa. Foram avaliados diversos algoritmos
utilizados por outros autores como estudo de caso, identificando suas características específi-
cas e ressaltando a importância de otimizações específicas para melhor aproveitamento destas
arquiteturas. Além disso, os autores apresentam uma forma de classificação dos algoritmos
quanto ao tipo de paralelismo; dispositivos disponíveis; padrão de acesso à memória e
sincronização.
Para avaliação dos resultados os autores se preocuparam somente na comparação de
desempenho entre CPUs e GPUs. Entretanto, não foi considerado o tempo de transferência de
dados entre os dispositivos. Foi considerado que os dados necessários já estivessem disponí-
veis na memória antes da execução, todavia, os autores argumentam que o tempo de transfe-
rência pode degradar significativamente o desempenho do algoritmo.
Os autores justificam que o paralelismo é praticamente linear quando se utiliza GPUs
multi-core, o desempenho está relacionado à quantidade de núcleos envolvidos e pela facili-
dade de utilização da memória cache que reduzem o tempo de acesso à memória, entretanto o
desempenho na CPU é diretamente relacionado à regularidade de acesso à memória. Por outro
lado o desempenho na GPU pode sofrer grandes impactos quando são necessárias sincroniza-
ções entre as threads, pois requerem chamadas do host.
3.6 Computação Heterogênea para Fluxos de Dados
Teodoro (2010) apud Ferreira et al. (2005) realizou um trabalho utilizando a ferramen-
ta proprietária Anthill com extensão para ambientes multi-core e heterogêneos. A ferramenta
oferece um ambiente de execução que implementa o modelo de programação filtro-fluxo.
Neste modelo as aplicações são desenvolvidas como um conjunto de unidades de processa-
mento, chamadas de filtros, que se comunicam através de fluxos de dados unidirecionais. Em
tempo de execução, entretanto, diversas instâncias de cada estágio de computação podem ser
criadas através do mecanismo de cópias transparentes.
O ambiente consiste em um conjunto de máquinas denominadas filtros que executam
as tarefas denominadas filtros, entretanto esses recursos são mapeados em uma unidade cen-
tral a qual contém os recursos de cada nodo de processamento e executa a distribuição das ta-
refas através de bibliotecas de comunicação distribuída como PVM ou MPI. A extensão de
Anthill para ambientes heterogêneos dá-se pela utilização de tratadores de eventos implemen-
35
tados para múltiplos dispositivos que podem ser CPUs e GPUs, no entanto não há limitações
para utilização de outros tipos de processadores.
A decisão pelo processador é feita sob demanda e acontece em tempo de execução,
sempre que existirem eventos e processadores disponíveis, ou seja, os eventos não são imedia-
tamente escalonados para um processador. A política de escalonamento utilizada é DDFCFS
(demand-driven, first-come, first-served) (TEODORO, 2010).
Figura 7 - Arquitetura dos filtros da aplicação no Anthill
Fonte: Teodoro, 2010.
Como pode ser observado na Figura 7, o ambiente Anthill, onde o filtro recebe os da-
dos através de três fluxos distintos, o “Escalonador de eventos” é o módulo responsável por
decidir quando e onde os eventos devem ser processados de acordo com a disponibilidade de
recursos. Ele cria processos e os associa ao dispositivo adequado, estes processos se comuni-
cam com o escalonador quando estiverem disponíveis. Em avaliações experimentares a distri-
buição de carga em CPU e GPU resultou em um ganho de 22,5% sobre a versão apenas GPU.
Entretanto sua principal contribuição está na forma como o desempenho relativo entre
os processadores é calculado antes da execução. Esta abordagem consiste em alocar a execu-
ção de cada tarefa no processador em que ela atinja maior desempenho, para isso os autores
propõem três módulos: “Escalonador de execuções”, “Escalonador intrafiltro” e “Estimador
de desempenho”, estes módulos estão interligados juntamente com o ambiente Anthill con-
forme pode ser observado na Figura 8.
36
Figura 8 – Arquitetura da integração do escalonamento proposto pelo autor
Fonte: Teodoro, 2010.
O “Estimador de desempenho” é responsável por calcular o desempenho relativo de
cada processador para uma determinada tarefa, e este valor é utilizado para decidir qual dispo-
sitivo é o mais adequado. Este cálculo é efetuado através de duas etapas: a primeira é a con-
sulta a uma base de conhecimento na qual são comparados os parâmetros de entrada; a segun-
da implementa um algoritmo de aprendizagem utilizando o algoritmo k-NN e os parâmetros
de entrada, assim, obtendo o desempenho relativo e alimentando a base de conhecimento.
O “Escalonador de execuções” mantém as filas de tarefas de cada dispositivo ordenada
pelo melhor desempenho previsto pelo estimador. Os resultados mostraram que o uso de am-
bos os dispositivos resultou em ganhos sobre a versão que utiliza somente GPUs em todos os
experimentos.
3.7 Eficiências de arquiteturas APUs
Daga, Aji, Feng (2011) realizaram uma análise de eficiência dos processadores hete-
rogêneos (APUs) da AMD visando obter resultados relativos ao tempo de transferência. Os
resultados mostraram que estas arquiteturas fornecem melhorias na faixa de 1,7 a 6,0x no
tempo de transferência de dados comparados com GPUs tradicionais, apesar de esta ter 20 ve-
zes mais núcleos, implicando em uma melhoria na transferência de dados reduzindo a sobre-
carga paralela, proporcionando assim maior paralelismo para a aplicação.
Neste trabalho os autores apresentam uma suposição de que a parte paralela do código
utiliza todos os núcleos disponíveis. Entretanto, isso só é possível se houver um mecanismo
de escalonamento perfeito que permita a total utilização dos recursos. Além disso, a sobrecar-
37
ga ocasionada pela paralelização utilizando GPU seria ainda maior porque os dados teriam
que ser transferidos através do barramento PCIe e não diretamente na memória.
Os testes foram realizados utilizando arquiteturas diferentes a fim de verificar a real
diferença obtida na utilização de APUs: um processador multi-core; uma CPU e uma GPU
PCIe; e uma APU. A Figura 9 mostra o tempo total de execução como a soma de:
a. o tempo de execução da parte de série;
b. o tempo de execução da parte paralela;
c. e a sobrecarga ocasionada devido à paralelização, ou seja, a criação, remoção e
transferência de buffer.
Figura 9 – Utilização do tempo de execução em diversas arquiteturas
Fonte: adaptado de Daga, Aji, Feng, 2011.
Entretanto, segundo os autores a afirmação de que APUS iriam superar o gargalo PCIe
em uma plataforma GPU nem sempre é válida. Os resultados mostraram que a largura de
banda obtida utilizando APUs aumenta conforme o aumento do tamanho da transferência de
dados, ou seja, APUs não fornecem o benefício prometido de superar os custos PCIe para pe-
quenas transferências de dados, todavia, há uma melhora significativa quando se aumenta o
tamanho dos dados. Além disso, é difícil saber esse ponto de cruzamento, uma vez que podem
variar de aplicação para aplicação (DAGA, AJI, FENG, 2011).
3.8 Análise dos trabalhos relacionados
Neste capítulo foram apresentados trabalhos que compõem o estado da arte no tema
proposto, como foi discutido no capítulo anterior, grande parte dos trabalhos relacionados está
concentrado na área de sistemas distribuídos, no entanto suas abordagens de escalonamento
38
são válidas quando se considera arquiteturas heterogêneas (APUs) que serão utilizadas no de-
senvolvimento. Como foi citado por Teodoro (2010) e Lee et al. (2011) a maior dificuldade
atualmente está em como alocar as tarefas para o processador mais adequado, juntamente com
os custos de sincronização e transferência de dados para os processadores envolvidos.
Por outro lado, a contribuição de Daga, Aji, Feng (2011) sugere que APUs sejam mais
eficiente do que GPUs discretas em alguns casos. No entanto o autor não aborda a utilização
dos núcleos GPU e CPU simultaneamente, além disso, o trabalho de Lee et al. (2011) também
não considera a utilização de arquiteturas integradas (APUs) fazendo com que muitos resulta-
dos destes autores possam variar ao considerar estas arquiteturas.
Todavia, a abordagem utilizada por Teodoro (2010) para avaliar o desempenho relati-
vo é bastante interessante, pois o desempenho relativo é estimado em tempo de execução,
permitindo uso mais eficiente da arquitetura e reduz a ociosidade dos processadores (especi-
almente CPUs) como ocorre nos trabalhos de Taifi, Khreishah, Shi (2011), Acosta et al.
(2011) e Ou, Chen, Lai (2011).
O quadro 1 mostra uma relação com os sete trabalhos relacionados numerados, que
servem como referência para o quadro 2. O quadro 2 mostra as abordagens, arquiteturas e
ambiente utilizados nos trabalhos relacionados e a proposta deste trabalho.
Quadro 1 – Trabalhos Relacionados
1) Taifi, Khreishah, Shi (2011)
2) Acosta et al. (2011)
3) Ou, Chen, Lai (2011)
4) Wang e Ren (2010)
5) Lee et al. (2011)
6) Teodoro (2010)
7) Daga, Aji, Feng (2011)
Fonte: Autoria própria, 2012.
39
Quadro 2 – Arquiteturas, abordagens e ambientes utilizados nos trabalhos relacionados.
Trabalhos Relacionados Trabalho
Proposto Assunto 1 2 3 4 5 6 7
Arq
uite
tura
CPU
GPU
APU
Abo
rdag
em
Escalonamento
Balanceamento de
carga
Análise
comparativa
Am
bien
te
Local
Distribuído
Fonte: Autoria própria, 2012.
A utilização de APUs neste trabalho foi escolhida por complementar o estudo dos au-
tores citados e contribuir para os avanços nos estudos sobre escalonamento nestas arquitetu-
ras. Para a realização deste trabalho será utilizado a interface de desenvolvimento OpenCL,
pois esta ser atualmente o padrão para o desenvolvimento em arquiteturas heterogêneas.
No próximo capítulo serão apresentados o ambiente de desenvolvimento OpenCL jun-
tamente com o desenvolvimento proposto.
40
4 DESENVOLVIMENTO
Neste capítulo, será apresentado o ambiente de execução e programação OpenCL, jun-
tamente com alguns conceitos relativos ao projeto de desenvolvimento de algoritmos para a-
plicações em arquiteturas heterogêneas. Também serão discutidas as ferramentas disponíveis
no estado da arte, a arquitetura do trabalho proposto e as aplicações que serão avaliadas.
4.1 Open CL (Open Computing Language)
OpenCL (KHRONOS GROUP, 2012) é um ambiente de desenvolvimento para aplica-
ções de propósito geral em plataformas heterogêneas equipadas com GPU, que tem como
principal objetivo manter a interoperabilidade entre placas gráficas de diferentes fabricantes.
Esse sistema inclui uma linguagem baseada em C99 para desenvolvimento de kernels,
que podem ser executados em diversos dispositivos e uma interface que permite o controle da
utilização da plataforma de execução. Os padrões de abstração e interfaces permitem ao pro-
gramador diversos níveis de paralelismo e mapeamento eficiente para dispositivos homogê-
neos ou heterogêneos como CPU, GPUs, e outros tipos de dispositivos (TEODORO, 2010).
4.1.1 O padrão OpenCL
O compilador OpenCL é construído em tempo de execução, oferecendo grande flexi-
bilidade e portabilidade onde as aplicações podem selecionar e utilizar dispositivos disponí-
veis em tempo de execução. As APIs OpenCL foram desenvolvidas para que se obtenha por-
tabilidade de código para arquiteturas de diferentes fabricantes. As especificações OpenCL
são definidas em quatro partes, chamadas modelos:
• Modelo de Plataforma especifica que há um processador que coordena a execução
(host) e um ou mais processadores que executam o código OpenCL (devices). O códi-
go é composto por funções (chamadas kernels) que são executadas pelos devices. O
modelo de plataforma define o relacionamento entre o host e o device.
• Modelo de Execução define como o ambiente OpenCL é configurado no host e como
os kernels são executados nos devices, incluindo configurações do contexto (context)
que é o mecanismo utilizado para promover a comunicação entre o host e os devices e
também define como os kernels serão executados.
41
• Modelo de Memória define as abstrações para as hierarquias de memórias utilizadas
pelos kernels quando executadas pelos devices.
• Modelo de Programação define como o modelo concorrente será mapeado para o
hardware.
Um cenário típico é a utilização de uma CPU x86 como host e uma GPU como device.
Neste trabalho será utilizado este cenário, apesar de APUs serem o mesmo dispositivo físico,
as abstrações OpenCL as consideram como dispositivos individuais.
4.1.2 Kernels e Modelo de Execução
Os kernels são partes de um programa OpenCL que são executadas pelo device e são
similares a funções C quando desenvolvidas utilizando threads ou OpenMP, no entanto nestes
casos não é preciso se preocupar com o excesso de recursos utilizados. Com OpenCL, deve-se
procurar o paralelismo em que se obtenha a granularidade mais fina possível (GASTER et al.,
2011).
Semelhante ao conceito de threads, o OpenCL utiliza o conceito de itens de trabalho
(work-itens) que são responsáveis pela execução do corpo do kernel no dispositivo. Os work-
itens são gerados em tempo de execução no momento em que o kernel é definido e neste pro-
cesso podem ser alocados para o dispositivo mais adequado. Os work-itens podem ser agru-
pados em grupos de trabalho (workgroup) de forma a facilitar operações de sincronização e
comunicação.
Os kernels são instâncias de operações paralelas. O corpo do kernel será executado
uma vez para cada work-item criado. Os parâmetros do kernel são semelhantes às funções em
C com o diferencial destes serem por somente ponteiros e poderem utilizar diretivas de me-
mória como global ou constant entre outras para permitir otimizações de hardware ou com-
partilhamento de variáveis entre os work-items.
O modelo de plataforma define as regras do relacionamento entre o host e os devices.
O host é responsável por coordenar a execução de um ou mais devices. No entanto, existe
uma restrição de compatibilidade entre dispositivos de fabricantes diferentes que não podem
ser utilizados no mesmo ambiente (GASTER et al., 2011).
42
4.1.3 Ambiente de execução
Em OpenCL, um contexto (context) é uma abstração do ambiente feita pelo host. Ele é
responsável por coordenar os mecanismos de iteração entre host e device, pelo gerenciamento
dos objetos de memória dos devices e controle das filas de comandos. Através do contexto
também é possível executar chamadas de eventos e controlar erros de em tempo de execução.
A Fila de Comandos (command queue) é um mecanismo utilizado pelo host para envi-
ar comandos para o device. Cada dispositivo no contexto tem uma fila de comandos associa-
da, facilitando o controle das tarefas que estão sendo executadas pelo dispositivo. As filas de
comandos são construídas em ordem, porém as execuções dos comandos podem ser feitas em
ordem ou fora de ordem, esta propriedade é definida no momento da criação da fila e não po-
de ser modificada.
A execução fora de ordem pode melhorar o desempenho das aplicações, no entanto,
isso pode resultar em altos custos de programação para garantir dependência dos dados
(GASTER et al., 2011). Em OpenCL, todas as operações feitas sobre filas geram eventos (e-
vents). Os eventos têm basicamente dois objetivos: representar as dependências de dados; e
disponibilizar mecanismos criação de perfis (profiling).
Os objetos de memória (memory objects) são os dados criados antes da execução que
são transferidos para o device. Existem dois tipos de objetos de memória: buffers e images.
Buffers são equivalentes a Arrays em C e são visíveis para todos os dispositivos associados
com o contexto no qual foi criado, opcionalmente podem ser definidos como somente leitura,
somente escrita ou leitura e escrita. Por outro lado, images são representações físicas de ima-
gens.
O código OpenCL executado no device é chamado programa (program). Portanto,
programa é um conjunto de funções (kernels) que são gerenciadas quando executadas no de-
vice. Os programas são compilados em tempo de execução, fazendo com que otimizações de
execução sejam modificadas a cada nova execução, por exemplo, a identificação dos disposi-
tivos envolvidos ou a quantidade de itens de trabalho.
O processo de criação de programas OpenCL segue três etapas:
a) O código pode ser armazenado em uma string de caracteres ou em um arquivo (.cl)
gravado no disco que é lido no momento da execução;
b) O código é lido e transformado em um objeto de programa (cl_program);
c) O objeto de programa é compilado para um ou mais devices.
43
Após este processo são geradas as instruções para cada tipo de dispositivo utilizado.
Para CPUs são geradas instruções que podem ser executadas diretamente no dispositivo; para
GPUs, neste caso AMD, é criado um código intermediário chamado IL (Intermediate Langa-
guge) que é uma linguagem de alto nível que representa um work-item que será compilado pa-
ra a arquitetura específica da GPU. Este processo é conhecido como código ISA (Instruction
Set Architecture). A NVIDIA utiliza uma abordagem semelhante para gerar código intermedi-
ário chamado PTX (Parallel Thread eXecution) (GASTER et al., 2011).
Após compilar o programa OpenCL é necessário extrair o kernel que será executado
no device, isto é feito através da chamada de função (clCreateKernel) na qual o nome do ker-
nel é um dos parâmetros e que retorna um objeto kernel OpenCL. Ao obter o kernel é neces-
sário definir os seus parâmetros que serão transferidos para o device no momento da execu-
ção, e após o kernel pode ser executado. As chamadas das funções de controle dos kernels são
assíncronas, no entanto, é possível controla-las através de eventos e/ou lista de eventos.
A Figura 10 apresenta o Ambiente de Execução OpenCL e a relação lógica entre os
componentes. Basicamente toda a interação entre os componentes ocorre através do contexto,
todavia, este processo pode ser dividido em três fases:
a) Compilação, onde são criados os programs e os kernels;
b) Definição dos dados, onde são criados os objetos de memória e definidos os parâ-
metros dos kernels;
c) Execução, onde as command queues são processadas nos devices.
Figura 10 – Ambiente de Execução OpenCL
Fonte: adaptado de Mattson et al., 2009.
44
4.1.4 Modelos de Memória
Para suportar as diversas estruturas de memória de diversos dispositivos, o OpenCL
utiliza um modelo de abstrações de memória que contribui para a portabilidade do código en-
tre diferentes fabricantes.
A Memória Global (global memory) é visível a todas as unidades de computação no
device, sendo muito similar à memória do sistema. Todos os dados transferidos do host para o
device são armazenados incialmente na memória global do dispositivo.
Memória Constante (constant memory) é uma memória de somente leitura, que é des-
tinada para ser utilizada por variáveis que são acessadas simultaneamente por muitas unidades
de trabalho. Ela fica armazenada na região da memória global de forma que todas as unidades
de processamento tem acesso ao seu valor.
A Memória Local (local memory) é uma parte da memória física do dispositivo que é
compartilhada somente pelo grupo de trabalho.
A Memória Privada (private memory) é a memória de acesso individual do item de
trabalho. Esta memória é destinada a variáveis locais internas do kernel que são na prática cri-
adas nos registradores do dispositivo (GASTER et al., 2011). O modelo de memória OpenCL
completo pode ser observado na Figura 11 que descreve o relacionamento entre a abstração de
memória OpenCL e a arquitetura da GPU AMD 6970.
Figura 11 – Relação entre o Modelo de Memória OpenCL e a arquitetura GPU AMD 6970.
Fonte: Gaster et al., 2011.
45
4.1.5 Ferramentas no Estado da Arte
Nesta subseção serão descritas as ferramentas para desenvolvimento em arquiteturas
heterogêneas utilizadas no estado da arte, juntamente com a justificativa da ferramenta esco-
lhida.
Estas ferramentas serão classificadas de acordo com suas funcionalidades, relaciona-
das com a proposta de desenvolvimento do trabalho proposto.
4.1.5.1 CUDA
O ambiente de programação CUDA (NVIDIA, 2012) foi utilizado pelos autores em
grande parte dos trabalhos (TAIFI, KHREISHAH, SHI, 2011; ACOSTA et al., 2011; OU,
CHEN, LAI, 2011; LEE et al., 2011; TEODORO, 2010). No entanto, como foi abordado no
início deste trabalho, a utilização do CUDA limita os dispositivos a somente produtos da Nvi-
dia.
Nestes casos, foi necessária a utilização de outras ferramentas juntamente com CUDA
para que a execução das tarefas pudesse ocorrer de maneira transparente em mais de um tipo
de dispositivo. Entretanto, é uma ferramenta bastante amadurecida e documentada que forne-
ce facilidades de integração com outras bibliotecas de desenvolvimento.
4.1.5.2 Anthill
Anthill é um ambiente de execução que implementa o modelo de programação filtro-
fluxo que foi utilizada por Teodoro (2010) para a criação de uma extensão que dá suporte a
ambientes heterogêneos e multi-core, utilizando bibliotecas do CUDA e MPI.
A vantagem deste modelo é a possibilidade de integração entre diversas bibliotecas
juntamente com a facilidade de mapeamento para ambientes distribuídos. Este ambiente tam-
bém permite que tarefas assíncronas sejam executadas entre os nodos de maneira concorrente
e oferecendo controle às ações cíclicas devido ao algoritmo de terminação.
4.1.5.3 OpenMP
O OpenMP (OPENMP ARCHITECTURE REVIEW BOARD, 2012) é uma API para
a programação multi-core de memória compartilhada em múltiplas plataformas e foi utilizada
46
em conjunto com CUDA em alguns dos trabalhos, tais com Ou, Chen, Lai (2011), Wang, Ren
(2010) e Daga, Aji, Feng (2011).
Esta API fornece muitas facilidades para a programação paralela, principalmente por
fornecer diretivas que tornam o paralelismo das operações implícito, oferecendo ao progra-
mador uma interface simples e flexível para o desenvolvimento de aplicações paralelas. Entre-
tanto, está limitada a CPUs sendo necessária a utilização em conjunto com outras bibliotecas
como o CUDA, por exemplo, para que seja aplicada em ambientes heterogêneos.
4.1.5.4 MPI (Message Passing Interface)
O MPI (MESSAGE PASSING INTERFACE FORUM, 2009) é um padrão de comu-
nicação entre processadores, entre nodos de clusters ou sistemas distribuídos. Neste modelo,
os processos se comunicam através da troca de mensagens. Foi utilizado nos trabalhos que
abordam sistemas distribuídos tais como em Taifi, Khreishah, Shi (2011), Acosta et al.
(2011), Ou, Chen, Lai (2011) e Teodoro (2010).
Este padrão geralmente está presente em aplicações distribuídas por facilitar a troca de
mensagens entre os nodos de computação, entretanto para a comunicação interna são utiliza-
das ferramentas mais transparentes como, por exemplo, o OpenMP ou CUDA. Sendo que esta
abordagem está fora do escopo do trabalho proposto.
4.1.5.5 OpenCL
O ambiente de desenvolvimento OpenCL (KHRONOS GROUP, 2012) é um padrão
entre diversos fornecedores para o desenvolvimento de aplicações paralelas com suporte a
processadores multi-core, processadores gráficos (GPUs) e outros tipos de processadores.
Sendo utilizado nos trabalhos de Daga, Aji, Feng (2011) que elaboraram uma análise compa-
rativa entre GPUs de APUs e GPUs discretas da Nvidia.
O OpenCL também oferece portabilidade de código entre diversas plataformas; permi-
te que o mesmo código seja destinado à processadores diferentes; é um padrão aberto e não
proprietário. Entretanto, ainda é uma ferramenta pouco amadurecida que ainda está ganhando
funcionalidades, e atualmente não oferece suporte nativo a sistemas distribuídos.
Estas características estão diretamente relacionadas com a proposta deste trabalho,
sendo que não será necessário reescrever o código para cada dispositivo envolvido, o ambien-
te será local e também fornece uma análise comparativa entre os dispositivos mais justa, pois
47
o desempenho de uma tarefa pode variar de acordo com a tecnologia utilizada (DE ROSE e
NAVAUX, 2003).
O quadro 3 mostra as ferramentas no estado da arte classificadas quanto ao suporte a
processadores multi-core, suporte a GPUs, suporte a ambientes heterogêneos, suporte a ambi-
entes distribuídos e suporte à bibliotecas externas.
Quadro 3 – Classificação das ferramentas do Estado da Arte
Ferramenta Suporte
multi-core
Suporte a
GPUs
Ambientes he-
terogêneos
Ambientes
distribuídos
Bibliotecas
externas
CUDA
Anthill
OpenMP
MPI
OpenCL
Fonte: Autoria própria, 2012.
4.2 Arquitetura proposta
Nesta seção será detalhada a arquitetura proposta e seus componentes. A arquitetura
deste trabalho é composta por três processos principais, dois dispositivos de processamento
(GPU e CPU) e duas interfaces de dados: entrada e saída.
4.2.1 Processos
São processos chave que fazem parte do fluxo principal do ambiente proposto, cada
processo tem uma função específica para cada etapa do processo geral. O Primeiro processo é
o Particionador, este processo recebe os dados de entrada, consulta Estimador de Desempenho
e divide o trabalho entre os processadores.
O Estimador de Desempenho recebe os parâmetros de entrada e estima o desempenho
relativo dos processadores. O processo sincronizador organiza os dados processados para
formar a saída. Os detalhes arquitetura podem ser observados na Figura 12 e serão descritos
no decorrer das próximas subseções.
48
Figura 12 – Arquitetura Heterogênea proposta
Fonte: Autoria própria, 2012.
4.2.1.1 Particionador
O Particionador é o processo responsável por particionar o trabalho em sub-tarefas pa-
ralelas e distribuí-las aos processadores. Este processo foi desenvolvido baseando-se na pre-
missa de que há variações de desempenho entre os processadores e que tais variações podem
ser previstas baseadas nos seus parâmetros.
Inicialmente são recebidos os parâmetros de entrada que são o tamanho do problema e
a granularidade utilizada. Essas informações serão obtidas pelo particionador em tempo de
execução, entretanto, estes são definidos antes da execução.
Assim, este processo não irá atribuir todas as tarefas ao processador mais adequado,
mas sim distribuir o trabalho entre todos os processadores, de forma que a diferença de tempo
de execução prevista seja a mais próxima de zero. Dessa forma, é possível explorar a hetero-
geneidade da arquitetura para todas as aplicações, todavia, o processador que obter o melhor
desempenho relativo irá executar uma carga de trabalho maior.
Ao receber os parâmetros iniciais, o trabalho será dividido pela metade e então esses
parâmetros serão enviados ao processo “Estimador de Desempenho” que irá retornar o de-
sempenho relativo de cada processador para esta carga de trabalho. Eventualmente este valor
será diferente para os processadores, então será recalculado o tamanho da carga dos processa-
dores até que a diferença de desempenho seja a menor possível.
49
Finalmente, o Particionador irá organizar e encaminhar as tarefas para os processado-
res juntamente com a quantidade de trabalho atribuída a cada um deles. Este processo pode
ser observado na Figura 13. Inicialmente, as sub-tarefas são definidas, após, alocadas para os
processadores disponíveis.
Figura 13 – Processo de particionamento entre CPU e GPU
Fonte: Adaptado de Boyer, Skadron, 2010.
Todavia, esse tipo de escalonamento pode ocasionalmente gerar desbalanceamento de
carga, principalmente por se tratar de uma estimativa de desempenho que visa equilibrar o de-
sempenho dos processadores e não a quantidade de carga em si, fazendo com que o tempo de
execução final seja definido pelo tempo do último processador que concluir sua carga de tra-
balho.
4.2.1.2 Estimador de desempenho
O Estimador de desempenho será responsável por automatizar a tarefa de previsão de
desempenho relativo entre dispositivos heterogêneos, baseando-se nos parâmetros da aplica-
ção, que no contexto deste trabalho, será o tamanho do problema e a granularidade que é a
quantidade de trabalho para cada item de trabalho (work-item).
Para isso será considerado o desempenho relativo dos processadores envolvidos, pois
se acredita que esta abordagem seja mais simples, sendo possível alcançar melhores resulta-
dos que na previsão de tempo de execução diretamente (TEODORO, 2010).
O Estimador de desempenho utilizará uma base de treinamento previamente estabele-
cida, proposta no próximo capítulo, e com base nesta, serão definidas a quantidade de trabalho
utilizada por cada processador. Como foi ressaltado por Teodoro (2010), “esta solução pro-
posta não tem a intenção de ser final, mas suficiente para os algoritmos de escalonamento
propostos”.
50
Diferentemente da proposta apresentada por Teodoro (2010), não será implementado o
algoritmo de aprendizagem, pois esta abordagem não está contida no escopo deste trabalho.
Entretanto, a previsão de desempenho relativo visa identificar as diferenças de desempenho
entre dois dispositivos na execução do mesmo programa.
4.2.1.3 Sincronizador
O processo Sincronizador é responsável pela sincronização e por receber os dados
processados pela CPU e GPU. Este processo foi desenvolvido partindo-se da premissa de que
os processadores irão concluir sua carga de trabalho em tempos diferentes, por isso é necessá-
rio que haja uma operação bloqueante para que possa ocorrer esta sincronização.
Basicamente o Sincronizar irá aguardar o fim do processamento total que será definido
pelo último processador que terminar sua execução. Posteriormente, os dados serão transferi-
dos dos dispositivos, sincronizados e organizados formando assim o resultado ou saída.
4.2.2 Dispositivos
Os dispositivos ou processadores serão responsáveis pela execução das tarefas defini-
das pelo escalonador. A proposta deste trabalho é a utilização de APUs que contém CPUs e
GPUs no mesmo chip, todavia, serão utilizados todos estes recursos de maneira cooperativa
com o objetivo de se obter um melhor desempenho final.
Inicialmente, ambos os dispositivos utilizarão o mesmo código (ou kernel OpenCL),
entretanto, com parâmetros distintos que foram definidos pelo escalonador em tempo de exe-
cução.
Esta abordagem implica no fato de que processadores diferentes estarão compartilhan-
do o mesmo código e trabalhando cooperativamente para resolver o problema final; neste pro-
cesso se caracteriza o conceito de computação heterogênea no contexto deste trabalho.
4.3 Modelo aplicado ao OpenCL
Nesta seção será discutido o modelo proposto aplicado ao ambiente de desenvolvi-
mento OpenCL. Inicialmente todas as interações deveriam ocorrer no mesmo contexto fazen-
do com que os dispositivos compartilhassem o mesmo objeto kernel, entretanto, esta aborda-
gem impede que o mesmo kernel seja executado com parâmetros diferentes.
51
Neste cenário, a solução encontrada foi a criação de dois objetos kernel no mesmo
contexto utilizando o mesmo código (source), entretanto, somente um kernel pode ser execu-
tado de cada vez, pois compartilham o mesmo objeto programa, além disso são necessárias
operações de sincronização entre eles o que pode impactar diretamente no desempenho final
da aplicação.
Finalmente foi necessário que cada dispositivo contenha seu próprio objeto program,
kernel e fila de comando, sendo assim desnecessárias operações de sincronização entre os
dispositivos. A partir da arquitetura proposta e das limitações da ferramenta utilizada, foi ela-
borado o modelo de execução que pode ser observado na Figura 14.
Figura 14 – Modelo aplicado ao OpenCL
Fonte: Autoria própria, 2012.
4.4 Executando o OpenCL
Nesta seção serão abordadas as aplicações utilizadas para análise e validação do traba-
lho proposto. Também serão apresentados os limites para a variação de parâmetros de cada
aplicação e a classificação por padrão de acesso à memória e complexidade. Inicialmente, fo-
ram utilizadas as quatro seguintes aplicações, que têm versões de kernel para CPU e GPU:
• General Matrix Multiply (GEMM) – Multiplicação Matricial
A Multiplicação Matricial é uma aplicação que faz parte de muitos algoritmos ligados
à álgebra linear, principalmente para solução de sistemas lineares. Esta aplicação geralmente
52
está presente em muitos trabalhos relacionados à computação de alto desempenho, sendo uma
das principais rotinas utilizadas no benchmark Linpack, que atualmente é utilizado para classi-
ficar os computadores no Top500 (TOP500.ORG, 2012).
Além disso, tem como característica padrões regulares de acesso à memoria, fazendo
com que seja facilmente implementado de maneira concorrente, outro fator importante a ser
considerado é que cada célula da matriz pode ser calculada de forma independente, tornado
desnecessárias operações de sincronização. Todavia, a complexidade de computação é O(n³) e
sua definição é dada por A x B, sendo A e B duas matrizes, para cada célula ABij tem-se:
������ � � ����
�1
• Vector Outer Product – Produto Vetorial Externo
O Produto Vetorial Externo é uma aplicação de álgebra linear comumente utilizado
para orientação espacial. Sua aplicação prática está principalmente atribuída no cálculo da á-
rea do paralelogramo e do triângulo, quando não são conhecidas as dimensões dos lados des-
tes objetos, mas sim a localização espacial de seus vértices. Também pode ser aplicado para o
cálculo do torque, que é uma grandeza física vetorial e está relacionada com a possibilidade
de um corpo sofrer uma torção ou alterar seu movimento de rotação (TOMIO, 2011).
O Produto vetorial é calculado a partir da multiplicação de dois vetores perpendicula-
res que resultam em uma matriz, além disso, tem como característica padrões de acessos regu-
lares à memória, o que facilitam sua implementação concorrente e apresenta complexidade
O(n²) quando os vetores têm a mesma dimensão. Sua representação é dada por u ⊗⊗⊗⊗ v, onde u
e v são vetores, e seu cálculo é definido por:
�� � ���������� ��� �� ��� � ����� ���� �������� ���� �������� ���� �������� ���� ����
�
• Single-precision real Alpha X Plus Y (SAXPY)
SAXPY é uma aplicação de álgebra linear que faz parte do pacote de bibliotecas Basic
Linear Algebra Subprograms (BLAS) e é uma aplicação comum utilizada no processamento
de vetores que combina multiplicação escalar e adição vetorial, sua definição é dada por: � � �� � �
onde α é a escala, e x e y são vetores com dimensões iguais. SAXPY foi utilizado por alguns
dos trabalhos relacionados e tem um padrão de acesso regular à memória que também facilita
sua implementação concorrente, além disso, sua complexidade é O(n) onde n é o tamanho do
vetor (NETLIB REPOSITORY, 2012).
53
• Parallel Sorting – Ordenação Paralela
Algoritmos de ordenação são utilizados em diversos cenários, inclusive banco de da-
dos. Para este trabalho será avaliado o algoritmo chamado Radix Sort, que foi utilizado em al-
guns dos trabalhos relacionados e é facilmente executado de maneira paralela independente.
O Radix Sort tem complexidade O(nk), onde n é o número de chaves, e k é o compri-
mento médio da chave. Este algoritmo utiliza o conceito de ordenação por contagem, porém
ele realiza a contagem com apenas uma parte da representação do elemento, sendo necessária
a repetição deste processo diversas vezes até que a representação total do elemento seja anali-
sada (GONÇALVES, SANTOS e SILLA, 2007).
Além disso, este algoritmo tem um padrão regular de acesso à memória, no entanto, o
acesso à memória é feito de maneira indireta e indexada (Gather/Scatter) de acordo com o va-
lor da chave, sendo necessária uma segunda lista que contém N valores diferentes de chave.
O quadro 4 apresenta a relação entre as aplicações analisadas juntamente com os limi-
tes para a variação de parâmetros de entrada, a classificação por padrão de acesso à memória e
complexidade.
Quadro 4 – Relação das aplicações analisadas
Algoritmo Aplicação Acesso à
memória Complexidade1
Variação
da entrada
General Matrix
Multiply
Álgebra Li-
near e Ma-
temática
Regular e
Assíncrono O(n³)
Tamanho do lado:
de 50 a 3k
Vector Outer
Product
Álgebra Li-
near e Física
Regular e
Assíncrono O(n²)
Tamanho dos vetores:
de 250 a 7k
SAXPY Álgebra Li-
near
Regular e
Assíncrono O(n)
Tamanho dos vetores:
de 1kk a 20kk
Radix Sort Banco de
dados
Regular,
Assíncrono e
Indexado
O(nk) Número de chaves:
de 1k a 1kk
Fonte: Autoria própria, 2012.
1 Complexidade do melhor algoritmo sequencial.
54
4.5 Considerações Finais
O capítulo de desenvolvimento deste trabalho demonstrou todas as etapas necessárias
para que seja possível construir o sistema proposto. Iniciou com uma visão geral do ambiente
de desenvolvimento OpenCL, seguido pelas ferramentas disponíveis no estado da arte e a mo-
tivação pela escolha desta ferramenta.
Posteriormente, foi descrita a arquitetura do sistema juntamente com os detalhes de
cada processo, seguido da representação da arquitetura aplicada ao modelo OpenCL.
O sistema demonstrado no capítulo 4 pode ser comparado com os sistemas descritos
no capítulo 3, entretanto, apresentamos pelo menos três diferenças principais:
a) o ambiente utilizado será local e não distribuído;
b) a arquitetura utilizada será APUs e não processadores multi-core com placas gráfi-
cas discretas;
c) e a ferramenta de desenvolvimento utilizada será OpenCL, pois esta abrange todas
as necessidades que estão no contexto deste trabalho.
Finalmente, foram discutidas as aplicações que serão utilizadas para análise e valida-
ção da nossa premissa definida na introdução. A proposta deste trabalho será avaliar as varia-
ções de desempenho destas aplicações.
A partir desta será formulada uma abordagem para estimar o desempenho relativo dos
processadores conforme são variados os parâmetros de entrada e granularidade. O objetivo
desta abordagem será estimar a diferença do tempo de processamento entre os processadores,
de forma que este seja o menor possível ao final da execução.
55
5 AVALIAÇÃO
Neste capitulo será descrita a metodologia de avaliação, os casos de treinamento e os
casos de teste submetidos à ferramenta proposta neste trabalho. Inicialmente será avaliada ca-
da uma das aplicações, utilizado cada tipo de processador separadamente com as variações de
entradas definidas no capítulo anterior.
Posteriormente, serão avaliados os dados obtidos para que se formule a abordagem pa-
ra previsão do desempenho relativo. Finalmente, serão apresentados os resultados obtidos
com a análise da proposta de estimativa de desempenho.
5.1 Metodologia de Avaliação
O trabalho proposto tem como problema principal o escalonamento de tarefas entre
CPU e GPU, na prática trata-se de um problema sem solução ótima em tempo polinomial.
Todavia, a metodologia utilizada é o escalonamento particionado que busca encontrar o ponto
de particionamento do problema onde o tempo de execução entre os processadores seja o mais
próximo possível.
Para isso, serão coletados os tempos de execução das aplicações, de forma que estas
informações sejam consideradas, para prever o desempenho utilizando ambos os dispositivos
para novas execuções.
Existem diversas formas para se estimar o desempenho de aplicações baseando-se em
tempos de execuções anteriores, entretanto estimar o tempo de execução de aplicações/tarefas
é um problema em aberto (TEODORO, 2010).
Uma abordagem comum para estimar o desempenho em ambientes heterogêneos é uti-
lizando benchmarks específicos para ambos os dispositivos e a partir dos resultados compara-
se o desempenho dos processadores envolvidos para uma nova aplicação. Esta metodologia
pode ser útil em casos onde não há conhecimentos sobre as características da nova aplicação,
entretanto, isso pode resultar em problemas de balanceamento de carga ou desperdiçar muito
tempo de processamento buscando a divisão mais próxima da ótima.
Uma alternativa seria o armazenamento do tempo de execução da aplicação para que
estes resultados sejam utilizados para estimar o tempo de execução de novas execuções, esta
metodologia pode ser combinada com algoritmos de aprendizagem, assim é possível obter
melhores execuções a cada nova execução.
56
5.1.1 Desempenho de Algoritmos Paralelos
O desempenho de uma aplicação está diretamente relacionado aos fatores característi-
cos do hardware que a executa, por isso é necessário identificar estes fatores para determinar
sua importância relativa ao desempenho global da aplicação (CASTRO, 2005).
Nos sistemas de computadores o desempenho pode ser definido de maneiras diferentes
(CASTRO, 2005), todavia, o objetivo de um algoritmo paralelo é obter um desempenho supe-
rior com relação à versão sequencial (ORELLANA, 2011).
O desempenho relativo entre duas máquinas é diretamente proporcional ao seu tempo
de execução (ORELLANA, 2011). Caso a carga de trabalho seja um número idêntico de ve-
zes, a média dos tempos de execução é válida na previsão dos tempos relativos em cada uma
das máquinas (CASTRO, 2005) e pode ser calculada a partir da seguinte Média Aritmética:
�� � ∑ "#$%&'&(� )
onde Tempoi é o tempo de execução do i-ésimo programa do total dos n pertencentes a carga
de trabalho (CASTRO, 2005).
Embora o desempenho de aplicações paralelas seja dependente do número de proces-
sadores, a forma de ligação desses processadores à memória e a existência de memória com-
partilhada, o desempenho final será definido pela tecnologia que as implementa (DE ROSE e
NAVAUX, 2003).
5.1.2 Metodologia para definição do número de variações
Uma das questões críticas deste trabalho é a quantidade de variações (ou classes) do
tamanho de entrada, que serão aplicadas para cada uma das aplicações. Para isso, preferiu-se
que todas estas deveriam ter o mesmo formato para facilitar o agrupamento destas variações.
A metodologia utilizada para obter este número de classes segue a Regra de Sturges
(CRESPO, 2002), que é definida através da seguinte equação: * 1 � 3,33 - log )
onde, k é o número de classes e n é o número de valores da variável.
Para determinar o número de valores possíveis, foi utilizada a média das diferenças re-
lativas entre os limites mínimo e máximo de cada aplicação, conforme a equação a seguir:
� � ∑ 12�& 3 �)&�)& 4'&(� )
57
onde, maxi é o limite máximo do tamanho da entrada, mini é o limite mínimo do tamanho da
entrada da aplicação e n é o número de aplicações utilizadas, que neste trabalho n = 4.
O valor min de cada aplicação foi definido a partir de seu tempo execução, onde foi
alcançado pelo menos um número significativo (em milissegundos). No entanto, o valor max
foi definido pouco antes de ocorrer falha ao alocar memória para a execução da aplicação.
Com isso foi obtido M = 254,5 e consequentemente, k = 9. Portanto, foi definido que
serão executadas nove variações de cada aplicação. Todavia, o tamanho das variações foi de-
finido aleatoriamente e aproximadamente distribuído entre os limites mínimo e máximo. Ob-
tendo assim, 36 amostras de execuções diferentes.
5.1.3 Metodologia de previsão do desempenho relativo
Para que a abordagem de previsão de desempenho relativo seja aplicada, são necessá-
rias duas etapas. Na primeira, quando uma nova aplicação é implementada, são realizadas um
conjunto de execuções da aplicação utilizando uma carga de trabalho igual para cada disposi-
tivo (CPU e GPU). Na segunda etapa, os dados coletados na primeira etapa são utilizados co-
mo parâmetros para o cálculo do desempenho relativo entre os dispositivos para uma nova
execução utilizando ambos os dispositivos cooperativamente.
Para a geração da base, são executadas cargas de trabalho do mesmo tamanho para
ambos os dispositivos e seus tempos de execução são armazenados, todavia, as cargas utiliza-
das derivam-se de nove variações (ou classes) dos intervalos que foram apresentadas na sub-
seção anterior.
O objetivo da segunda etapa é estimar o desempenho do processador propriamente di-
to, para que isso ocorra é gerado o “Fator de Desempenho” (FD), que é calculado pela seguin-
te equação:
567 � 89"
onde, FDA é o Fator de Desempenho para a aplicação A; tT é o tempo médio de execução para
uma carga de trabalho de tamanho T em um determinado processador.
O desenvolvimento desta equação segue basicamente os conceitos definidos por Cas-
tro (2005). Por isso, o objetivo de se calcular o FD é obter uma relação entre o tempo de exe-
cução e o tamanho do problema.
Os valores obtidos serão utilizados como parâmetro para estimar as diferenças de de-
sempenho entre os processadores. Embora em algumas aplicações este fator seja praticamente
58
fixo para todos os tamanhos do problema, para outras aplicações o FD pode sofrer grandes va-
riações conforme o tamanho total do problema.
Embora existam diversas estratégias para estimar o desempenho em processadores,
optou-se por utilizar o Fator de Desempenho a fim de se obter uma base de estimativa relati-
va. Todavia a precisão desta metodologia depende necessariamente da precisão do tempo de
execução da aplicação.
A utilização desta metodologia não visa estimar o tempo de execução, mas sim obter a
quantidade de trabalho para cada processador a partir desta métrica. Todavia, isto implica em
aceitar que todas as sub-tarefas têm o mesmo impacto para o tempo total de execução, o que
pode não ser verdade na prática, pois estas dependem das características próprias da aplicação
utilizada, laços e desvios.
Entretanto, com isso é obtido o desempenho médio do processador, o que pode ser vá-
lido para avaliar o desempenho para tarefas com padrão irregular de acesso à memoria. Toda-
via são necessários mais testes para validação desta premissa. Essa é uma das melhorias que
poderiam ser feitas no estimador de desempenho proposto, além de avaliar outras aplicações.
Para esta análise, também não serão considerados os tempos de transferência por pelo
menos dois motivos:
a) Nas arquiteturas APUs, CPUs e GPUs compartilham o mesmo barramento para
acesso à memória, isso implica em taxas de transferências muito próximas, pois a
distância à memoria e o barramento de transferência são os mesmos;
b) Em todos os testes realizados, o tempo de transferência resultou em no máximo
0.1% do tempo total de execução, o que não resulta em impactos significativos na
avaliação final.
5.1.4 Fator de balanço de carga ou razão de sincronização (FLB)
A avaliação dos resultados obtidos irá seguir o Fator de Balanço de Carga
(ORELLANA, 2011). Esta métrica visa avaliar qualitativamente a precisão da sincronização
entre processos paralelos após a execução.
O cálculo do Fator de Balanço de Carga é dado a partir da seguinte equação:
5:; � "<=> 3 "<&'"<=>
59
onde, Tmax é o tempo do último processo a terminar; Tmin é o tempo do primeiro processo a
terminar. O FLB é um indicativo de balanço de carga do algoritmo e seus valores variam de 0
até 1, onde 1 é a situação indesejável (Tmax >> Tmin) e 0 é a situação ótima (Tmax ≈ Tmin).
5.2 Coleta dos dados
Os dados apresentados nesta seção foram obtidos executando a primeira fase do esti-
mador com uma carga de trabalho de 30 execuções para variação, as quais foram executadas
nos dois processadores: CPU e GPU. A configuração utilizada foi o processador A8-3870k,
que é a primeira geração de APUs da AMD, e 8GB de memória de sistema. Os erros de previ-
são são calculados utilizando a técnica 10-fold cross-validation e k = 10, pois esse valor de k é
bastante difundido na literatura.
Seguindo a metodologia de 10-fold cross-validation, foi feita a avaliação das previsões
realizadas pelo estimador utilizando as 30 execuções de cada aplicação, cujos resultados são
apresentados na Tabela 1.
Tabela 1 – Erro médio na previsão para o tempo de execução
Aplicações Erro médio do tempo de execução (%)
CPU GPU
General Matrix Multiply 48,70 31,31
Vector Outer Product 61,25 10,56
SAXPY 15,83 11,73
Radix Sort 32,56 5,61
Fonte: Autoria própria, 2012.
Com os dados obtidos é possível observar as diferenças na previsão de desempenho
entre os processadores, onde a GPU obteve índice de previsão melhor que a CPU em todos os
casos. Seguindo-se a metodologia de avaliação foi calculado o tempo médio de execução para
todas as cargas de trabalho que serão avaliadas nas próximas seções.
Nas próximas seções serão apresentadas as variações de desempenho com as variações
de cada aplicação que foram descritas no capítulo anterior. Para todas as análises, foi conside-
rado como unidade de medida padrão para avaliação do tempo sendo em milissegundos.
• General Matrix Multiply
60
No Gráfico 1 são apresentadas as variações de desempenho para a aplicação de Multi-
plicação de Matriz conforme é modificado o tamanho do problema. É possível observar que
em todas as variações avaliadas a GPU obteve maior desempenho, todavia essas diferenças
variam conforme o tamanho do problema aumenta.
Gráfico 1 – Variações de desempenho para Multiplicação de Matriz
Fonte: Autoria própria, 2012.
Para a primeira variação (50x50) a GPU foi aproximadamente 3x mais eficiente que a
CPU, entretanto para uma matriz 3000x3000 a GPU apresentou desempenho 13x melhor que
a CPU.
• Vector Outer Product
No Gráfico 2 são apresentadas as variações de desempenho para a aplicação Produto
Vetorial Externo conforme são modificados o tamanho do problema. É possível observar que
em todas as variações avaliadas a GPU obteve maior desempenho, no entanto essas variações
são diferentes das apresentadas para a Multiplicação de Matriz.
0,1
1
10
100
1000
10000
100000
1000000
50 150 300 500 700 1000 1500 2200 3000
Te
mp
o (
mil
ise
gu
nd
os)
Tamanho do Lado da Matriz
CPU
GPU
61
Gráfico 2 – Variações de desempenho para Produto Vetorial Externo
Fonte: Autoria própria, 2012.
Para a primeira variação (250) a GPU obteve um desempenho 4x mais eficiente que a
CPU, mas para a última variação avaliada esta diferença foi de aproximadamente 9x.
• SAXPY
No Gráfico 3 são apresentadas as variações de desempenho para a aplicação SAXPY
conforme são modificados o tamanho do problema. Para todas as variações aplicadas a GPU
obteve desempenho superior à GPU, todavia esta variou somente entre 8x e 9x.
Gráfico 3 - Variações de desempenho para a aplicação SAXPY
Fonte: Autoria própria, 2012.
• Radix Sort
No Gráfico 4 são apresentadas as variações de desempenho para a aplicação SAXPY
conforme são modificados o tamanho do problema. Observa-se que a GPU obteve melhor de-
0,01
0,1
1
10
100
1000
250 500 1000 2000 3000 4000 5000 6000 7000
Te
mp
o (
mil
ise
gu
nd
os)
Tamanho dos Vetores
CPU
GPU
0,1
1
10
100
Te
mp
o (
mil
ise
gu
nd
os)
Tamanho dos Vetores
CPU
GPU
62
sempenho que a CPU em termos gerais, entretanto, para a primeira variação o desempenho de
ambos os processadores foi idêntico.
Gráfico 4 - Variações de desempenho para o algoritmo Radix Sort
Fonte: Autoria própria, 2012.
Todavia, a medida em que o número de chaves aumenta, as diferenças entre os proces-
sadores torna-se mais significativa, chegando a pouco mais de 5x para 100000 chaves.
5.3 Ferramenta de Análise – AMD APP Profiler
Para a coleta dos dados foi utilizada a ferramenta AMD APP Profiler (ADVANCED
MICRO DEVICES, 2012c), que é uma extensão para a ferramenta de desenvolvimento Visual
Studio 2010. A AMD APP Profiler permite a análise de desempenho e reúne dados dos tem-
pos de execução OpenCL para dispositivos AMD.
Esta ferramenta apresenta dados estatísticos sobre a execução de uma aplicação e estes
dados podem ser utilizados para analisar e otimizar o desempenho das aplicações, descobrir
pontos críticos e acompanhar a duração das execuções de cada chamada OpenCL.
A vantagem de utilizar esta ferramenta para coleta de dados é sua precisão, além disso,
torna desnecessárias implementação de contadores de tempo dentro do código. Também exis-
tem outras facilidades que esta ferramenta oferece, mas que não são necessárias no contexto
deste trabalho.
A Figura 15 apresenta a interface Timeline da ferramenta, nesta visualização é possí-
vel analisar a linha do tempo, a ordem em que as chamadas OpenCL foram executadas e sua
visualização gráfica. Também se pode obter informações detalhadas sobre cada chamada O-
penCL, tais como momento da chamada, duração, índice, etc.
0,1
1
10
100
1000
10000
Te
mp
o (
mil
ise
gu
nd
os)
Número de Chaves
CPU
GPU
63
Figura 15 – Interface Timeline da ferramenta AMD APP Profiler
Fonte: Autoria própria, 2012.
A ferramenta também oferece a interface Session. Esta interface relaciona somente os
kernels que foram executados, sua ordem de execução, tempo de execução e outras informa-
ções úteis sobre a utilização e performance do dispositivo. Os detalhes desta interface podem
ser observados na Figura 16.
Figura 16 – Interface Session da ferramenta AMD APP Profiler
Fonte: Autoria própria, 2012.
64
Particularmente esta interface é de grande importância para coleta das informações de
execução das aplicações, principalmente por gerar automaticamente um arquivo de log (.csv)
que pode ser exportado para análise em ferramentas mais robustas.
5.4 Análise Experimental
Essa seção tem como objetivo analisar experimentalmente a segunda etapa do estima-
dor de desempenho para validação do trabalho proposto. Para isso foi seguida a mesma meto-
dologia de análise dos dados. Foram feitas 30 execuções com cada variação e a partir dos da-
dos obtidos foi calculado o tempo médio destas execuções.
A segunda etapa do estimador proposto depende dos dados obtidos na primeira etapa
que foram descritos na seção 5.2. Todavia a segunda etapa do estimador segue os seguintes
critérios:
a) Cada uma das sub-tarefas têm de ser alocada para somente um processador;
b) A quantidade de sub-tarefas será proporcional ao desempenho relativo entre os
processadores;
c) Caso não se obtenha a partição ótima, o melhor processador ficará com maior
quantidade de trabalho;
d) Em todos os casos, as sub-tarefas serão geradas buscando obter a granularidade
mais fina possível.
O algoritmo que implementa estes critérios necessita de um conhecimento prévio so-
bre o desempenho dos processadores para a execução da aplicação. Por isso foi necessário a
geração da base de dados de desempenho dos processadores na primeira etapa.
Também é necessário o conhecimento do tamanho total do problema, que na prática
será a quantidade de sub-tarefas. Tendo estas informações, é calculada a quantidade de tarefas
para cada processador, obedecendo aos critérios estabelecidos.
O funcionamento prático deste algoritmo é semelhante ao adotado por Acosta (2011).
Todavia a principal diferença é que o algoritmo utilizado estima o desempenho antes de alo-
car as sub-tarefas aos processadores.
A quantidade de iterações também não é limitada, porém suas iterações são interrom-
pidas quando todos os critérios definidos sejam aceitos como verdadeiro. O cálculo para a
proporção da quantidade de trabalho é feito seguindo a seguinte equação: 6 � 567 - ?
65
onde, D é o desempenho do processador; FD é o fator de desempenho do processador para a
aplicação A; Q é quantidade de sub-tarefas.
Com isso se obtém a quantidade de sub-tarefas proporcional ao desempenho relativo
dos processadores. O objetivo desta equação é obter 6@AB C 6DAB , onde DCPU é o desempe-
nho da CPU para sua quantidade de sub-tarefas e DGPU é o desempenho da GPU para sua
quantidade de sub-tarefas.
Na próxima seção serão discutidos os resultados obtidos com a metodologia e suas li-
mitações. Também será avaliada qualitativa e quantitativamente a precisão da metodologia u-
tilizada com o propósito de validar nossa premissa apresentada na introdução.
5.5 Resultados Experimentais
Nesta seção serão apresentados os resultados quantitativos obtidos ao aplicar a meto-
dologia estabelecida nas seções anteriores. Para isso, foram executadas 30 cargas de trabalho
para cada variação de cada aplicação.
Após a coleta dos resultados foi calculado o desvio padrão amostral do tempo de exe-
cução para cada conjunto de amostras obtidas, estas informações podem ser observadas na
Tabela 2, onde cada linha representa uma variação do tamanho do problema. Os detalhes das
variações serão apresentados no decorrer desta seção.
Tabela 2 – Desvio padrão amostral dos resultados
Nº. Mult. Matriz Prod. Vet. Ext. SAXPY Radix Sort
CPU GPU CPU GPU CPU GPU CPU GPU
1 0,033 0,028 0,015 0,027 0,027 0,030 0,060 0,029
2 0,271 0,019 0,035 0,068 0,058 0,065 0,054 0,132
3 1,024 0,110 0,073 0,099 0,163 0,058 1,040 0,227
4 5,018 0,169 0,292 0,259 0,164 0,096 1,503 0,136
5 11,66 1,228 1,047 0,653 0,214 0,710 0,253 0,179
6 10,93 2,991 0,996 2,576 0,302 0,322 0,664 0,094
7 74,83 5,502 0,967 1,686 0,314 0,551 14,85 0,240
8 80,03 24,93 0,456 3,241 0,360 0,378 28,68 0,285
9 69,96 82,05 0,493 4,984 0,393 0,492 66,06 0,197
Fonte: Autoria própria, 2012.
66
Ao observar o conjunto de desvios padrão dos resultados, nota-se que a CPU geral-
mente apresenta maiores variações de desempenho quando comparados com a GPU, entretan-
to, para as aplicações utilizadas, a CPU obteve menor desempenho em quase todos os casos.
Este fato pode contribuir positivamente para a eficiência do algoritmo que estima o
desempenho entre estes processadores, pois visa sempre subestimar o processador mais lento.
Nas próximas subseções serão apresentados os resultados quantitativos, obtidos se-
guindo as variações de cada aplicação, que foram descritas na seção anterior. Para esta análi-
se, também foi considerado como unidade de medida padrão, para avaliação do tempo, em
milissegundos. Em todas as representações, nas abscissas localiza-se o tamanho da variação e
nas ordenadas localiza-se o tempo de execução.
5.5.1 General Matrix Multiply
No Gráfico 5 são representados os resultados obtidos utilizando a metodologia de par-
ticionamento de tarefas estabelecida. É possível observar que o desempenho da CPU se man-
teve sempre igual ou menor ao desempenho da GPU na maioria dos casos, este comportamen-
to já era esperado conforme os critérios de particionamento estabelecidos.
Gráfico 5 – Resultados General Matrix Multiply
Fonte: Autoria própria, 2012.
Também se destaca a precisão da metodologia para esta aplicação, em especial para os
tamanhos 150, 300 e 500. Nestes casos as diferenças nos tempos de execução ficaram muito
0,1
1
10
100
1000
10000
100000
50 150 300 500 700 1000 1500 2200 3000
Te
mp
o (
mil
ise
gu
nd
os)
Tamanho do Lado da Matriz
CPU
GPU
67
próximas do ótimo. Entretanto, nas demais variações a diferença máxima se manteve abaixo
de 10%.
Na Tabela 3 são apresentados os detalhes das variações analisadas, a quantidade de
sub-tarefas, o tamanho da carga de trabalho para cada processador e seu respectivo tempo de
execução.
Tabela 3 – Detalhes das variações General Matrix Multiply
Variação Quantidade de
sub-tarefas
Tamanho da Carga Tempo de Execução
CPU GPU CPU GPU
1 2500 617 1883 0,191172 0,185733
2 22500 3346 19154 2,086667 2,266110
3 90000 11176 78824 13,91404 13,62148
4 250000 26263 223737 61,21357 61,43303
5 490000 46435 443565 165,0140 170,0562
6 1000000 92012 907988 472,5972 499,5519
7 2250000 176789 2073211 1673,512 1715,244
8 4840000 353211 4486789 5239,543 5445,935
9 9000000 639243 8360757 13225,70 13808,38
Fonte: Autoria própria, 2012.
Quanto à quantidade de sub-tarefas, pode-se notar que a GPU ficou com a maior parte
da carga de trabalho em todos os casos, entretanto, para a primeira e terceira variação, seu
tempo de execução foi cerca de 3% melhor que o tempo da CPU.
5.5.2 Vector Outer Product
Seguindo com a análise, foram coletados os tempos de execução para a aplicação Vec-
tor Outer Product. No Gráfico 6 pode-se observar as variações do tempo de execução, onde a
GPU também obteve maiores valores na maioria dos casos.
68
Gráfico 6 – Resultados Vector Outer Product
Fonte: Autoria própria, 2012.
Para esta aplicação, o equilíbrio entre os tempos de execução se manteve próxima de
15% em todos os casos. Na Tabela 4 são apresentados os detalhes das variações analisadas, a
quantidade de sub-tarefas, o tamanho da carga de trabalho para cada processador e seu respec-
tivo tempo de execução.
Tabela 4 – Detalhes das variações Vector Outer Product
Variação Quantidade de
sub-tarefas
Tamanho da Carga Tempo de Execução
CPU GPU CPU GPU
1 62500 11703 50797 0,084686 0,072521
2 250000 52597 197403 0,323399 0,315092
3 1000000 189802 810198 1,155120 1,292297
4 4000000 472192 3527808 2,939687 3,180676
5 9000000 980438 8019562 7,346743 6,362805
6 16000000 1644292 14355708 10,03953 11,21843
7 25000000 2519945 22480055 15,46476 16,73319
8 36000000 3455205 32544795 20,47371 23,87432
9 49000000 4792512 44207488 28,52702 32,46662
Fonte: Autoria própria, 2012.
Analisando os detalhes das execuções, nota-se que a GPU também executou a maior
parte da carga de trabalho em todos os casos, no entanto, as diferenças nos tempos de execu-
ção permaneceram muito próximas em todas as variações.
0,01
0,1
1
10
100
250 500 1000 2000 3000 4000 5000 6000 7000
Te
mp
o (
mil
ise
gu
nd
os)
Tamanho dos Vetores
CPU
GPU
69
5.5.3 SAXPY
A próxima aplicação avaliada foi Single-precision real Alpha X Plus Y. Os resultados
obtidos nesta aplicação estão apresentados no Gráfico 7. Os dados estão representados em
uma escala de tempo menor em relação às outras aplicações, entretanto, seu desempenho foi
praticamente linear ao tamanho do problema.
Gráfico 7 – Resultados SAXPY
Fonte: Autoria própria, 2012.
Para esta aplicação, o equilíbrio entre os tempos de execução se manteve abaixo de
10% em todos os casos. Na Tabela 5 são apresentados os detalhes das variações analisadas, a
quantidade de sub-tarefas, o tamanho da carga de trabalho para cada processador e seu respec-
tivo tempo de execução.
Tabela 5 – Detalhes das variações SAXPY
Variação Quantidade de
sub-tarefas
Tamanho da Carga Tempo de Execução
CPU GPU CPU GPU
1 1000000 103655 896345 0,162080 0,174475
2 3000000 356175 2643825 0,481252 0,476343
3 5000000 523637 4476363 0,816055 0,776608
4 7000000 731543 6268457 1,136348 1,170035
5 10000000 948394 9051606 1,689516 1,902226
0
0,5
1
1,5
2
2,5
3
3,5
4
Te
mp
o (
mil
ise
gu
nd
os)
Tamanho dos Vetores
CPU
GPU
70
6 13000000 1128805 11871195 2,027306 2,110626
7 15000000 1273683 13726317 2,314539 2,460363
8 17000000 1451603 15548397 2,652954 2,742913
9 20000000 1871554 18128446 3,116659 3,341373
Fonte: Autoria própria, 2012.
Ao analisar os dados da Tabela 5 nota-se que a GPU executou aproximadamente 10x
mais trabalho que a CPU. Todavia, seus tempos de execução se mantiveram muito próximos.
Também se observa que a GPU obteve tempo de execução maior do que a CPU, com exceção
da terceira variação, onde a CPU foi aproximadamente 5% menos eficiente que a GPU.
5.5.4 Radix Sort
Finalmente, foi avaliado o algoritmo de ordenação Radix Sort. Os resultados obtidos
nesta aplicação estão apresentados no Gráfico 8. Como pode ser observado, o tempo máximo
de execução foi definido pelo tempo de processamento da GPU na maioria dos casos.
Gráfico 8 – Resultados Radix Sort
Fonte: Autoria própria, 2012.
Para esta aplicação, o equilíbrio entre os tempos de execução apresentou grandes vari-
ações principalmente ao ordenar 30.000 chaves. Na Tabela 6 são apresentados os detalhes das
variações analisadas, a quantidade de sub-tarefas, o tamanho da carga de trabalho para cada
processador e seu respectivo tempo de execução.
0,1
1
10
100
1000
10000
Te
mp
o (
mil
ise
gu
nd
os)
Número de Chaves
CPU
GPU
71
Tabela 6 – Detalhes das variações Radix Sort
Variação Quantidade de
sub-tarefas
Tamanho da Carga Tempo de Execução
CPU GPU CPU GPU
1 1000 501 499 0,551349 1,150867
2 3000 745 2255 2,986728 2,268359
3 5000 1033 3967 5,124933 5,761554
4 7000 1327 5673 9,217087 9,117943
5 10000 1792 8208 21,39613 16,99685
6 30000 4823 25177 184,4228 136,5522
7 50000 8106 41894 383,7351 365,9812
8 70000 11405 58595 788,6459 703,8301
9 100000 16231 83769 1561,673 1436,885
Fonte: Autoria própria, 2012.
Analisando os detalhes das variações para esta aplicação, observa-se que, com exceção
da primeira variação, a GPU executou maior carga de trabalho na maioria dos casos. Entretan-
to, ao considerar o tempo de execução, houveram poucas situações onde o equilíbrio atingiu
valores próximos do ótimo.
5.6 Análise dos Resultados
O objetivo desta seção é analisar quantitativa e qualitativamente os resultados como
forma de validar nossa premissa. Para isso serão feitas duas abordagens: primeiramente será
avaliada a sincronização entre os processadores; após, os dados serão comparados com outras
técnicas de particionamento estáticas comumente utilizadas em ambientes heterogêneos.
5.6.1 Análise Qualitativa
Esta subseção visa avaliar a precisão da metodologia de particionamento de tarefas pa-
ra a sincronização dos processadores. Para isso, será utilizado o Fator de Balanço de Carga,
conforme foi descrito na seção 5.1.4.
A metodologia do Fator de Balanço de Carga não está diretamente relacionada à com-
putação heterogênea, entretanto, será utilizada com a finalidade de validar um dos objetivos
do trabalho proposto que é obter a diferença no tempo de execução dos processadores mais
próxima de zero.
72
A Tabela 7 exibe os resultados da análise qualitativa considerando como parâmetro o
Fator de Balanço de Carga.
Tabela 7 – Avaliação: Fator de Balanço de Carga
Variação Mult. Matriz Prod. Vet. Ext. SAXPY Radix Sort
1 0,028452563 0,143647735 0,071043471 0,520927417
2 0,079185624 0,025685532 0,010200477 0,240520199
3 0,021025838 0,106149775 0,048338654 0,110494726
4 0,003572356 0,075766703 0,028791438 0,010756472
5 0,029650169 0,133928509 0,111821624 0,205610736
6 0,053957770 0,105086498 0,039476440 0,259569803
7 0,024330141 0,075803179 0,059269295 0,046266156
8 0,037898203 0,142437832 0,032797002 0,107546193
9 0,042197497 0,121343147 0,067252188 0,079906355
Média 0,035585573 0,103316546 0,052110065 0,175733117
Fonte: Autoria própria, 2012.
Ao analisar o nível de sincronização dos processadores, observa-se que a metodologia
utilizada obteve melhores resultados no algoritmo de Multiplicação de Matriz. Nesta aplica-
ção, o Fator de Balanço de Carga médio foi pouco maior que 0.03, que é um indicador muito
próximo do ótimo, também foi obtido o melhor FLB absoluto (0,0035).
O segundo melhor resultado foi obtido com o algoritmo SAXPY, onde seu FLB médio
foi de aproximadamente 0.05, que também é um índice próximo do ótimo. O terceiro melhor
resultado foi alcançado no algoritmo do Produto Vetorial Externo, onde o FLB médio obtido
foi de cerca de 0.1.
Finalmente, o pior índice de sincronização obtido foi com no algoritmo Radix Sort on-
de o FLB médio foi pouco maior que 0.17, que também representa um bom nível de sincroni-
zação. Entretanto, nesta aplicação foi obtido o pior FLB absoluto (0.52) na primeira variação.
De forma geral, o FLB médio se manteve em 0.09, o que representa um bom índice de
sincronização entre os processadores. Portanto, com estes resultados pode-se afirmar que o
algoritmo de particionamento obteve boa precisão ao estimar as cargas de trabalho para os
processadores.
73
5.6.2 Análise Quantitativa
Nesta subseção serão apresentadas as análises quantitativas dos resultados, para isso
serão utilizadas duas abordagens de particionamento estático como referência, que geralmente
são aplicados em ambientes heterogêneos.
O objetivo desta subseção é avaliar o desempenho final das aplicações utilizando a
metodologia proposta em relação às técnicas mais usuais. Para isso, será considerado como
unidade de avaliação o speedup, que indica quanto um algoritmo paralelo é mais eficiente
comparado à versão sequencial. O speedup é calculado a partir da seguinte equação:
E � "�"F
onde, T1 é o tempo da versão sequencial e Tp é o tempo da versão paralela com p processos.
5.6.2.1 Utilizando somente o melhor processador
Uma das técnicas mais comuns de particionamento de tarefas em ambientes heterogê-
neos é a partição estática, onde se utiliza somente o melhor processador. De maneira geral,
toda a carga de trabalho é destinada somente para o processador que obter o melhor desempe-
nho relativo.
Com isso são obtidos bons resultados (conforme pode ser observado nos gráficos a se-
guir), no entanto, esta metodologia implica em deixar o processador menos eficiente ocioso
ou com pouca participação no processamento geral.
5.6.2.2 Utilizando ambos os processadores com partição estática
Outra técnica que também pode ser utilizada em ambientes heterogêneos é o particio-
namento estático de tarefas. Esta técnica consiste em dividir o problema entre os processado-
res sem considerar índices de desempenho.
A consequência de se utilizar esta técnica é a subutilização do processador mais efici-
ente, pois o tempo final de processamento será definido pelo processador mais lento.
74
5.6.2.3 Desempenho da metodologia proposta
Definidas as abordagens de referência, foram analisados os resultados obtidos com a
metodologia proposta em relação às metodologias convencionais. O objetivo desta abordagem
é otimizar o tempo de processamento final, particularmente, melhorar o desempenho do me-
lhor processador.
Portanto, utilizando todos os recursos possíveis do processador mais lento, sem que es-
te influencie negativamente no tempo de execução final. Os Gráficos 9, 10, 11 e 12 apresen-
tam os resultados quantitativos obtidos ao aplicar a metodologia proposta.
Gráfico 9 – Desempenho Final do algoritmo Multiplicação de Matriz
Fonte: Autoria própria, 2012.
Ao analisar o aumento do speedup, a metodologia proposta obteve melhor desempe-
nho em todas as variações do tamanho do problema. Quando comparado com o Particiona-
mento Estático, foram obtidos ganhos até 7x maiores, no entanto, quando comparados com a
metodologia, utilizando somente o melhor processador, o ganho médio foi de 10%.
A próxima aplicação avaliada foi o Produto Vetorial Externo, os resultados estão re-
presentados no Gráfico 10. Nesta aplicação, o speedup utilizando a metodologia proposta teve
um aumento médio de cerca de 3% maior que a metodologia que utiliza somente o melhor
processador.
0
10
20
30
40
50
60
50 150 300 500 700 1000 1500 2200 3000
Sp
ee
du
p
Tamanho do Lado da Matriz
Melhor Processador Particionamento Estático
Metodologia Proposta
75
Gráfico 10 – Desempenho Final do algoritmo Produto Vetorial Externo
Fonte: Autoria própria, 2012.
Entretanto, para o tamanho de entrada igual a 3000, o desempenho foi cerca de 10%
pior. Isto ocorreu porque neste caso, o tempo de execução foi definido pelo processador mais
lento, ou seja, houve superestimação do desempenho relativo da CPU.
Todavia, o maior ganho foi obtido para o tamanho de entrada igual a 500, onde o de-
sempenho da metodologia proposta alcançou speedup cerca de 20% maior que utilizando so-
mente o melhor processador.
Finalmente, o ganho médio sobre a metodologia de Particionamento Estático foi cerca
de 4,5x. No entanto, estes ganhos variam de cerca de 3x na primeira variação, até cerca de 6x
na última variação.
Seguindo com a análise, foi avaliado o desempenho da aplicação SAXPY utilizando a
metodologia proposta. Os resultados estão expressos no Gráfico 11.
0
5
10
15
20
25
30
35
250 500 1000 2000 3000 4000 5000 6000 7000
Sp
ee
du
p
Tamanho dos Vetores
Melhor Processador Particionamento Estático
Metodologia Proposta
76
Gráfico 11 – Desempenho Final do algoritmo SAXPY
Fonte: Autoria própria, 2012.
Nesta aplicação em particular, foram obtidos os maiores ganhos percentuais em rela-
ção às outras técnicas analisadas. Isto se deve ao fato em que o melhor processador foi pouco
mais eficiente que o processador mais lento. Portanto, resultando numa melhor eficiência da
metodologia proposta.
Em quantidades percentuais, o ganho médio de speedup foi cerca de 70% quando
comparada com a técnica utilizando somente o melhor processador. No entanto, a maior dife-
rença obtida na segunda variação, onde se obteve speedup aproximadamente de 2,25x maior e
o pior caso ocorreu na quinta variação, onde foi obtido ganho de cerca de 43%.
Ao considerar a técnica de Particionamento Estático, as diferenças foram ainda maio-
res, em média 7,85x melhor, mas variando de seis a nove vezes melhor.
A última aplicação analisada foi o algoritmo de ordenação Radix Sort. Os resultados
obtidos nesta aplicação estão apresentados no Gráfico 12.
0
5
10
15
20
25
Sp
ee
du
p
Tamanho dos Vetores
Melhor Processador Particionamento Estático
Metodologia Proposta
77
Gráfico 12 – Desempenho Final do algoritmo Radix Sort
Fonte: Autoria própria, 2012.
Finalmente, analisando esta aplicação, observam-se os resultados mais excêntricos
dentre as aplicações. Ao avaliar a primeira variação, o melhor speedup foi obtido com o Parti-
cionamento Estático. Isto ocorreu porque os processadores tiveram desempenhos praticamen-
te iguais ao executar somente metade do trabalho.
Outro fato que degradou o desempenho da metodologia proposta foi a superestimação
do processador mais lento. Isto afetou praticamente todas as variações do tamanho do pro-
blema, mas resultou em perdas mais significativas para a quinta e sexta variações.
No entanto, os melhores resultados apresentaram ganhos de até 12%, mesmo quando o
tempo final foi definido pelo processador mais lento. Apesar de o speedup médio apresentar
perdas cerca de 2% comparados com a técnica que utiliza somente o melhor processador, ob-
tiveram-se ganhos superiores a 2x comparados com o Particionamento Estático.
5.7 Considerações Finais
O capítulo de avaliação deste trabalho demonstrou todos os processos utilizados para
obter os resultados discutidos. Inicialmente, com a metodologia de avaliação, onde foram de-
finidas as estratégias para mensurar o desempenho das aplicações paralelas e definidas as
classes de variações avaliadas. Também foi definida a metodologia de previsão de desempe-
nho e validação do sincronismo entre os processadores conforme a literatura propõe.
0
5
10
15
20
25
1000 3000 5000 7000 10000 30000 50000 70000 100000
Sp
ee
du
p
Número de Chaves
Melhor Processador Particionamento Estático
Metodologia Proposta
78
A partir destas definições, foram coletados os dados que serviram para alimentar o es-
timador de desempenho. Este processo foi facilitado graças à AMD APP Profiler, que fornece
grande precisão nos tempos de execução. A partir dos dados coletados nesta etapa, observa-se
que a GPU obteve melhor desempenho em praticamente todas as variações das aplicações a-
nalisadas.
Após a coleta dos dados, foram definidos os critérios utilizados pelo estimador de de-
sempenho para particionar o problema entre os processadores. Esta metodologia consiste ba-
sicamente em destinar a maior parte do trabalho para o processador mais eficiente, de forma
que o tempo final sempre seja definido pelo processador mais rápido, todavia, deve-se obter a
menor diferença possível nos tempos de execução entre os processadores.
Com os resultados experimentais apresentados, foi avaliada a qualidade das amostras
através do desvio padrão amostral. Neste processo, observou-se que a CPU obteve maior irre-
gularidade amostral, fato que contribuiu positivamente para a precisão da metodologia pro-
posta.
A partir dos resultados experimentais, avaliou-se a metodologia obedecendo aos crité-
rios definidos. A análise qualitativa teve como objetivo avaliar a qualidade da sincronização
entre os processadores no final da execução, para isso, foi utilizado o Fator de Balanço de
Carga, onde se concluiu que a metodologia proposta obteve resultado médio próximo do óti-
mo em todas as aplicações avaliadas.
Por fim, os resultados obtidos aplicando a metodologia proposta foram comparados
com técnicas usualmente utilizadas em ambientes heterogêneos. Com estes resultados, obser-
vam-se ganhos que são inversamente proporcionais à diferença de desempenho relativo entre
os processadores, ou seja, quanto menor a diferença no desempenho entre os processadores
(CPU e GPU), maiores foram os ganhos sobre as técnicas mais estáticas.
Além disso, os ganhos de speedup foram diretamente dependentes da precisão da es-
timativa do desempenho relativo dos processadores, ou seja, para situações onde o processa-
dor mais lento foi superestimado, os resultados apresentaram perdas significativas, que degra-
daram o desempenho final da aplicação. Entretanto, ao superestimar o processador mais rápi-
do foram obtidos resultados que, no pior caso, se iguala à melhor técnica de particionamento
estático atual.
79
6 CONCLUSÕES
Neste capítulo será apresentada a síntese das ideias propostas no decorrer do trabalho,
os desafios encontrados, as soluções propostas e os resultados obtidos. Também serão apre-
sentadas as limitações e deficiências da metodologia proposta e, finalmente, as direções apon-
tadas para trabalhos futuros.
6.1 Sumário dos Resultados
Neste trabalho foi estudado o problema de escalonamento de tarefas em ambientes he-
terogêneos utilizando CPUs e GPUs. O objetivo deste trabalho está diretamente relacionado
com a investigação de uma abordagem de distribuição de tarefas, buscando reduzir o tempo
ocioso dos processadores, especialmente o mais lento (geralmente a CPU), melhorando assim
o desempenho final da aplicação nestes ambientes.
A partir da definição da hipótese e objetivos, foi necessário observar diretamente o es-
tado da arte, pois o conceito de computação heterogênea, especialmente com o uso de GPUs,
atualmente esta dependente de bibliotecas proprietárias específicas para somente um tipo de
processador. No entanto, tem sido impulsionada principalmente pelo grande interesse destas
arquiteturas na área da computação de alto desempenho.
A programação GPGPU também apresentou grande influência para o desenvolvimento
de arquiteturas heterogêneas, visto que a GPU pode obter melhor desempenho que a CPU em
diversos cenários. Atualmente o desenvolvimento de arquiteturas nativamente heterogêneas,
tais como as APUs, fez com que a heterogeneidade do hardware alcançasse o público domés-
tico em grande escala.
Os experimentos dos trabalhos relacionados forneceram informações importantes para
o desenvolvimento da proposta, principalmente por estas apresentarem algumas soluções para
problemas característicos destas arquiteturas, tais como, abordagem de distribuição de tarefas,
metodologias para estimar o desempenho relativo e características das aplicações que se bene-
ficiam com cada tipo de processador.
Entretanto, a maioria destes trabalhos visa melhorar o escalonamento de tarefas entre
os nodos de ambientes distribuídos, e muitas vezes não se preocupam com a divisão do traba-
lho no interior do nodo, o que muitas vezes resulta na subutilização do processador mais len-
to, reduzindo a eficiência destes ambientes.
80
Assim se fez necessário o desenvolvimento de uma arquitetura que visa contornar al-
gumas destas dificuldades. Para isso, foi apresentado o OpenCL, que provê a utilização de vá-
rios tipos de processadores de maneira transparente e também aparece como padrão de desen-
volvimento de aplicações em ambientes heterogêneos.
O OpenCL fornece abstrações dos componentes físicos, isso contribui para a portabili-
dade do código utilizando diversos tipos de dispositivos simultaneamente. Além disso, tam-
bém abrange os requisitos necessários para o desenvolvimento da arquitetura proposta.
A modelagem da arquitetura teve como objetivo ilustrar o relacionamento entre os
processos necessários para o particionamento e execução das tarefas, utilizando os recursos
computacionais disponíveis. Contudo, houve limitações lógicas entre as abstrações que defini-
ram o modelo aplicado ao OpenCL, por isso, foi definido que haveria abstrações individuais
para cada dispositivo. No entanto, as instruções da aplicação sendo compartilhadas entre os
dispositivos.
Após estas definições, foram escolhidas quatro aplicações que serviram como bench-
marks para avaliar a eficiência da metodologia proposta. Estas aplicações apresentam caracte-
rísticas diferentes de execução, o que contribuiu para a diversidade da granularidade das tare-
fas aplicadas à arquitetura proposta.
O funcionamento do sistema visa particionar o problema de maneira proporcional ao
desempenho dos processadores envolvidos. Isso o classifica como cooperativo, pois cada a-
plicação será executada utilizando o máximo de recursos disponíveis em cada processador.
No entanto, o desempenho é calculado a partir de execuções anteriores do mesmo pro-
blema em cada aplicação. Esta abordagem de particionamento pode gerar desbalanceamento
de carga intencional, pois o objetivo desta estratégia é obter a menor diferença de desempenho
entre os processadores ao final da execução.
O algoritmo responsável pelo particionamento das sub-tarefas implementa critérios
que visam aproveitar ao máximo os recursos de cada processador, no entanto, procura-se su-
perestimar o melhor processador. O objetivo destes critérios é fazer com que, no pior caso, o
desempenho final seja igual ao desempenho do melhor processador, sem que o processador
mais lento interfira no tempo de execução final.
Portanto, foi obtida boa qualidade de sincronização no tempo de execução dos proces-
sadores, este objetivo foi validado a partir da métrica Fator de Balanço de Carga. Com estes
resultados alcançamos o objetivo principal deste trabalho, onde o sincronismo médio se man-
teve próximo do ótimo.
81
Para validar os objetivos secundários da proposta, foram utilizadas como referência
duas técnicas estáticas que usualmente são aplicadas em ambientes heterogêneos. Os resulta-
dos obtidos demonstraram que a utilização conjunta dos processadores alcançou melhor de-
sempenho em todos os casos onde o processador mais lento não foi superestimado.
Todavia, o pior caso ocorreu quando o tempo máximo foi definido pelo processador
mais lento. Esta situação implicou em pelo menos dois efeitos negativos: menores ganhos no
desempenho final e ociosidade do melhor processador.
No entanto, para os melhores casos, foram obtidos resultados que superam as técnicas
estáticas atuais. Estas situações foram favorecidas quando o processador mais rápido é ligei-
ramente mais eficiente que o processador mais lento ou quando há pouca variação no desem-
penho médio do processador mais lento.
Estes fatores afetaram positivamente a eficiência da metodologia proposta, onde os re-
sultados percentuais médios foram 20% mais eficientes que a melhor técnica de particiona-
mento estático e cerca de cinco vezes mais eficaz do que simplesmente particionar as tarefas
sem algum critério.
Finalmente, os melhores resultados foram obtidos quando os processadores apresenta-
ram pouca diferença entre suas margens de variação de desempenho. Esta situação não ocor-
reu no algoritmo Radix Sort e acabou gerando um efeito em cascata que degradou o desempe-
nho final desta aplicação.
6.2 Limitações e Trabalhos Futuros
As limitações deste trabalho estão diretamente ligadas às limitações das tecnologias u-
tilizadas. Nesta categoria, há pelo menos duas limitações significativas que impediram melho-
res resultados.
Apesar de a memória do sistema ser compartilhada fisicamente, ela não pode ser aces-
sada diretamente por qualquer processador devido à sua partição lógica, isto limita à GPU
somente 512MB. Sendo necessárias transferências de dados entre os blocos de memória, que
podem prejudicar o desempenho destas arquiteturas. Todavia, espera-se que nas próximas ge-
rações de APUs não hajam estas limitações.
O ambiente OpenCL fornece diversas facilidades para controlar operações de maneira
assíncrona, tais como leitura, escrita e transferência de dados entre os dispositivos. No entan-
to, operações de chamada de kernel são bloqueantes e seguem a lógica sequencial que foi dis-
82
parada. Entretanto, espera-se que com o amadurecimento desta tecnologia isto seja possível
em suas próximas versões.
Para complementar este trabalho serão descritas algumas sugestões que motivam a
continuação do mesmo, sendo apresentadas a seguir:
a) as otimizações propostas nesse trabalho assumem que a aplicação já está em exe-
cução e tem o conhecimento do desempenho relativo dos processadores. Portanto,
seria interessante a utilização de algoritmos de aprendizagem como forma de au-
tomatizar este processo;
b) considerar os desvios amostrais ao particionar as tarefas entre os processadores. Is-
so resultaria em melhor precisão nas estimativas e melhor desempenho final;
c) executar outras aplicações utilizando a mesma metodologia, especialmente aplica-
ções que têm padrões irregulares de acesso à memória;
d) considerar o tempo de transferência entre os dispositivos e o host;
e) avaliar o particionamento de diferentes aplicações simultaneamente;
f) aplicar esta metodologia em outras arquiteturas, tais como GPUs discretas, para
avaliação em diferentes tipos de barramentos.
83
REFERÊNCIAS
ACOSTA, A. et al. Dynamic Load Balancing on Heterogeneous Multicore/MultiGPU Systems. IEEE Computer Society, p. 467-476, 2011.
ADVANCED MICRO DEVICES. AMD Accelerated Processing Units, 2012a. Disponivel em: <http://www.amd.com/us/products/technologies/fusion/Pages/fusion.aspx>. Acesso em: 4 Ago 2012.
ADVANCED MICRO DEVICES. AMD FireStream, 2012b. Disponivel em: <http://www.amd.com/uk/products/server/processors/firestream/Pages/firestream.aspx>. Acesso em: 4 Ago 2012.
ADVANCED MICRO DEVICES. AMD APP Profiler , 2012c. Disponivel em: <http://developer.amd.com/tools/hc/AMDAPPProfiler/Pages/default.aspx>. Acesso em: 4 Ago 2012.
ALVES, A. Início da era da APU AMD Fusion. Guia do PC, 05 Janeiro 2011. Disponivel em: <http://www.guiadopc.com.br/noticias/16741/inicio-da-era-da-apu-amd-fusion.html>. Acesso em: 12 Ago 2012.
BOYER, M.; SKADRON, K. Task Sharing: Collaborative CPU-GPU Execution, 2010. Disponivel em: <http://www.cs.virginia.edu/~mwb7w/publications/TECHCON_10_task_sharing.pdf>. Acesso em: 1 Set 2012.
CASE, L. Dual Graphics: Increasing Performance in AMD APU Systems. PCWorld , 05 Julho 2011. Disponivel em: <http://www.pcworld.com/article/235064/dual_graphics_increasing_performance_in_amd_apu_systems.html>. Acesso em: 1 Set 2012.
CASTRO, M. C. S. D. Organização de Computadores I. Rio de Janeiro: Universidade do Estado do Rio de Janeiro, 2005.
CRESPO, A. A. Estatística Fácil. 17ª. ed. São Paulo: Saraiva, 2002.
DAGA, M.; AJI, A. M.; FENG, W.-C. On the Efficacy of a Fused CPU+GPU Processor (or APU) for Parallel Computing. IEEE Computer Society, Washington, n. 29, p. 141-149, 2011.
DE ROSE, C. A. F.; NAVAUX, P. O. A. Arquiteruras Paralelas. Porto Alegre: Editora Sagra Luzzatto S/A, 2003.
EKMECIÉ, I.; TARTALJA, I.; MILUTINOVIÉ, V. EM3: A Taxonomy of Heterogeneous Computing Systems. Computer, v. 28, n. 12, p. 68-70, Dez 1995.
84
GASTER, B. R. et al. Heterogeneous Computing with OpenCL. Massachusetts: Morgan Kaufmann, 2011.
GONÇALVES, A. R.; SANTOS, L. G. A. D.; SILLA, P. R. Algoritmos de Ordenação. Londrina: Universidade Estadual de Londrina, 2007.
INTEL. Many Integrated Core (MIC) Architecture. Intel , 2012. Disponivel em: <http://www.intel.com/content/www/us/en/architecture-and-technology/many-integrated-core/intel-many-integrated-core-architecture.html>. Acesso em: 5 Ago 2012.
KAUER, A. U.; SIQUEIRA, M. L. D. Balanceamento de Carga em Sistemas Paralelos Heterogêneos Baseados em GPU. Escola Regional de Alto Desempenho, Erechim, Março 2012. 149-152.
KHRONOS GROUP. OpenCL, 2012. Disponivel em: <http://www.khronos.org/opencl>. Acesso em: 4 Ago 2012.
LEE, V. et al. Debunking the 100X GPU vs. CPU Myth: An Evaluation of Throughput Computing on CPU and GPU. SIGARCH Comput. Archit. News, v. 38, n. 3, p. 451-460, 2011.
MAHESHWAR, P. A Dynamic Load Balancing Algorithm for a heterogeneous Computing Environment. IEEE Computer Society, Washington, v. 1, n. 29, p. 338-346, 1996.
MATTSON, T. et al. OpenCL: A Standard Platform for programming Heterogeneous parallel computers, p. 1-140, 2009. Disponivel em: <http://software.intel.com/sites/default/files/m/e/1/8/4/5/24571-OpenCL-tut-sc09.pdf>. Acesso em: 5 Set 2012.
MESSAGE PASSING INTERFACE FORUM. Message Passing Interface Forum. MPI , 2009. Disponivel em: <http://www.mpi-forum.org>. Acesso em: 11 Ago 2012.
NETLIB REPOSITORY. BLAS (Basic Linear Algebra Subprograms). Netlib Repository at UTK and ORNL , 2012. Disponivel em: <http://www.netlib.org/blas/>. Acesso em: 5 Ago 2012.
NVIDIA. CUDA, 2012. Disponivel em: <http://www.nvidia.com.br/cuda>. Acesso em: 5 Ago2012.
OPENMP ARCHITECTURE REVIEW BOARD. OpenMP, 2012. Disponivel em: <http://openmp.org/wp/>. Acesso em: 14 Ago 2012.
85
ORELLANA, E. T. V. Caracterização de desempenho em programas paralelos, Santa Cruz, 2011. Disponivel em: <http://nbcgib.uesc.br/nbcgib/files/2011_pp/Aula02_caract_progs_paralelo.pdf>. Acesso em: 5 Set 2012.
OU, Y.; CHEN, H.; LAI, L. A Dynamic Load Balance on GPU Cluster for Fork-Join Search. IEEE Computer Society, Beijing, p. 592-596, Set 2011.
OWENS, J. D. et al. GPU Computing. IEEE Computer Society, v. 96, n. 5, p. 879-889, Maio 2008.
SPAFFORD, K.; MEREDITH, J.; VETTER, J. Maestro: Data Orchestration and Tuning for OpenCL Devices. IEEE Computer Society, Berlin, p. 275-286, Out 2010.
TAIFI, M.; KHREISHAH, A.; SHI, J. Y. Natural HPC Substrate: Exploitation of Mixed Multicore CPU and GPUs. IEEE Computer Society, Philadelphia, p. 33-40, Jul 2011.
TEODORO, G. L. M. Computação em Fluxos de Dados para Ambientes Paralelos e Heterogêneos. 2010. 132 f. Tese apresentada ao Programa de Pós-Graduação em Ciência da Computação do Instituto de Ciências Exatas. Universidade Federal de Minas Gerais, Belo Horizonte, 2010.
TOMIO, J. C. Material Básico de Estudo Vetores e Álgebra Vetorial. Instituto Federal de Santa Catarina [IFSC], Joinville, 2011. Disponivel em: <http://www.joinville.ifsc.edu.br/~julio.tomio/Outros%20Materiais/Mat%20Ensino%20-%20Geom%20Analitica%202011-02-01.pdf>. Acesso em: 21 Ago 2012.
TOP500.ORG. Top 500 List. TOP 500 Computers, 2012. Disponivel em: <http://www.top500.org/lists/2011/11>. Acesso em: 12 Mar 2012.
WANG, G.; REN, X. Power-efficientWork Distribution Method for CPU-GPU Heterogeneous System. IEEE Computer Society, Washington, p. 122-129, 2010.