Escalonamento de tarefas em arquiteturas heterogêneas - APUS

86
ANDERSON UILIAN KAUER ESCALONAMENTO DE TAREFAS EM ARQUITETURAS HETEROGÊNAS – APUS CANOAS, 2012

Transcript of Escalonamento de tarefas em arquiteturas heterogêneas - APUS

ANDERSON UILIAN KAUER

ESCALONAMENTO DE TAREFAS EM ARQUITETURAS HETEROGÊNA S – APUS

CANOAS, 2012

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

À Adi Kauer e Leandro Kauer À Leandro Júnior e Vagner Kauer

À Nadith C. S. Kauer

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.