SlideShare uma empresa Scribd logo
1 de 46
Baixar para ler offline
Programando Multicore com IBM-full System Simulator – Cell Broadband Engine
Jussara M. Kofuji, Sergio T. Kofuji, Roberto K. Hiramatsu
PAD-LSI/USP – Universidade de São Paulo
Av. Prof. Luciano Gualberto trav3 Cidade Universitária, 158 – São Paulo - CEP: 05508-970
{jussara, kofuji, kenji}@pad.lsi.usp.br
Leonardo A. G. Garcia
IBM Brasil – Centro de Tecnologia Linux – LTC
Rod. Jornalista Francisco Aguirre Proença, km 09 – Hortolândia, SP – CEP: 13186-900
lagarcia@br.ibm.com
Resumo
Este minicurso pretende apresentar novos conceitos de programação de uma arquitetura heterogênea chamada
“Cell Broadband Engine”, desenvolvida por um consórcio formado por Sony, Toshiba e IBM. Atualmente esta
arquitetura está presente no PlayStation 3, na IBM Blade Cell QS21 e tem proposta para ser implementada na TV
Digital, sendo utilizada para resolver problemas que demandam uma computação de alto desempenho e alta
resolução de imagem. As arquiteturas multicore, em geral, estão impulsionando o desenvolvimento de aplicações de
alto desempenho que utilizam técnicas de programação que exploram o paralelismo de hardware e software. O
minicurso visa introduzir o uso do Simulador para plataforma Cell, apresentando o ambiente de desenvolvimento
provido pelo recente lançamento do Cell SDK 3.0 e o IDE baseado em Eclipse para o Cell SDK. Faremos uma
introdução sobre o uso do IDE: criação de projetos, compilação e debug de aplicações com o Cell System Simulator
e otimização de código usando-se os mecanismos de comunicação entre processadores providos pela arquitetura Cell
Broadband Engine.
Capítulo 1: Introdução à Arquitetura Cell BE
1. Introdução
Nosso mini-curso é baseado essencialmente na Arquitetura “Cell Broadband Engine”
(Cell BE), considerada uma arquitetura heterogênea. Atualmente, podemos destacar dois tipos de
arquiteturas multicore: arquitetura multicore homogênea (como por exemplo, Intel Core 2 Duo
ou Quadcore, UltraSPARC T1/T2) e arquiteturas multicore heterogênea (Processador Cell BE,
Processadores Intel com GPU/FPGA).
Conceitualmente, a arquitetura multicore homogênea, segundo Jonathan [1] em sua tese
intitulada “Evolve: A Preliminary Multicore Architecture for Introspective Computing”, é uma
arquitetura com blocos homogêneos enfileirados, ou seja, cada núcleo é idêntico ao outro. Em
contrapartida, numa arquitetura heterogênea os blocos formadores podem ser diferentes e ter,
inclusive, funções especializadas.
Na figura 1 e 2, apresentamos respectivamente, exemplo de arquitetura homogênea e
arquitetura heterogênea.
Figura 01: Arquitetura Multicore Homogêneo [1]
Figura 02: Sistema Cell Broadband Engine [2]
Como citado anteriormente, a partir da Aliança IBM, SCEI/Sony e Toshiba formada em 2000,
começou a trajetória do desenvolvimento do processador Cell. Em 2001, iniciou-se o
desenvolvimento da arquitetura Cell BE no Centro de Pesquisa da IBM em Austin, Texas. Tanto
o hardware quanto o software foram e estão sendo desenvolvidos simultaneamente. Em 2003, a
Toshiba projetou a memória XDR DRAM que hoje equipa algumas das máquinas com
processadores Cell BE. Esta memória é capaz de operar em velocidades de barramento mais
altas, quando comparadas às memórias convencionais. Esta característica é essencial para se ter
um bom aproveitamento do poder de processamento provido pelo processador Cell BE, pois ele
possui um desenho inovador no seu barramento de comunicação interno que possibilita uma
grande taxa de transferência interna entre núcleos e entre os núcleos e a memória externa. Em
2004, a arquitetura Cell BE é apresentada à comunidade acadêmica na conferência internacional
de circuitos de estados sólidos (ISSCC’2005). Em 2005, foi anunciado o lançamento do
PlayStation 3 pela Sony. E, finalmente, em 2006, a IBM ganha a licitação do Laboratório de Los
Alamos para desenvolver o supercomputador RoadRunner baseado no processador Cell BE.
A versão inicial do processador Cell BE foi implementada em sistemas de console de jogos
(PlayStation 3 – PS3) pela Sony, posteriormente em servidores com dois processadores Cell,
linha de servidores chamada IBM Blade Cell (atualmente, modelo QS20) e a proposta de
implementação do processador na tecnologia HDTV pela Toshiba, em especial, em servidores
“home media”. está sendo usada em alguns produtos que exigem grande poder computacional:
sistemas de console de jogos (PlayStation3), Blades (IBM Blade Cell), HDTV, servidores de
“home media” e supercomputadores. Apesar destas plataformas comerciais equipadas com
processador Cell BE, existe um plano em aberto pelo consórcio para continuar a evolução da
arquitetura como veremos adiante neste mini-curso.
Em termos de software, as três empresas do consórcio, além de empresas parceiras, também
tiveram participação no desenvolvimento de suas plataformas de desenvolvimento de aplicações
para o processador Cell BE. Especificamente neste mini-curso iremos comentar sobre o Cell BE
SDK da IBM, que é a única plataforma de desenvolvimento para processadores Cell BE
fornecida gratuitamente. O IBM Cell BE SDK passou pelas seguintes fases: versão alpha (SDK
1.1), versão beta (SDK 2.0 e SDK 2.1) e versão “produto” (SDK 3.0). Já em termos de hardware,
tivemos uma evolução de escalabilidade do PCI express e memória (1 GB, 2 GB).
O processador Cell BE foi desenvolvido especialmente para jogos, aplicações multimídia e
outros tipos de aplicações que necessitem de alto poder de computação numérica. Já existem
diversos trabalhos relacionados com processamento de imagens (como ressonância magnética),
análise de imagens, criação de conteúdo digital (jogos e filmes), distribuição de conteúdo,
próxima geração da física baseada em visualização, vídeo conferência, aplicações de streaming
(codecs), simulações físicas e ciência [3]. Recentemente, a IBM divulgou um caso de estudo
baseado em aplicações para o mercado financeiro [4].
Este primeiro capítulo de introdução à arquitetura Cell BE está organizado nos seguintes
tópicos: Arquitetura Cell BE e seus Elementos, Cell BE Roadmap, Cell SDK 3.0.
1.1 Público Alvo
Este mini-curso foi planejado com intuito de oferecer uma visão mais aprofundada da
Arquitetura Multicore Heterogênea – o Processador Cell Broadband Engine, apresentar as
potencialidades desta arquitetura para aplicações que demandam um alto poder de computação
(em especial, área de processamento de imagens, visualização e computação gráfica, modelos
matemáticos, algoritmos numéricos paralelos, geociência, aeroespacial, biomédica, arquitetura de
computadores, programação paralela). Outros objetivos específicos são: introduzir conceitos
básicos de programação na plataforma Cell BE, apresentar modelos de programação e o uso do
simulador da IBM, bem como as ferramentas externas de otimização de códigos e análise de
performance.
Nosso mini-curso começou a partir das atividades de pesquisa desenvolvidas na disciplina de
Arquiteturas Avançadas de Computadores da Escola Politécnica da Universidade de São Paulo
(EPUSP), de visitas técnicas do Engenheiro Chefe do desenvolvimento do processador Cell BE –
Peter Hosftee, da participação em um projeto do Cell BE no Programa IBM Extreme Blue e
parceria técnica para desenvolver o Centro de Competência Cell no Brasil.
A princípio, o mini-curso destina-se a todos interessados em aprender os novos paradigmas de
programação multicore heterogêneo, alunos e pesquisadores da área de Arquitetura de
Computadores que se interessam por processadores modernos, simuladores, compiladores,
programação paralela; pesquisadores e profissionais que desejam desenvolver aplicações
científicas na plataforma Cell BE; engenheiros e pesquisadores interessados em programação
para processamento de áudio e vídeo; alunos, físicos e pesquisadores interessados em simulação
de Fluídos Dinâmicos; e finalmente médicos e pesquisadores interessados em Ressonância
Magnética.
2. Arquitetura Cell BE e seus Elementos
Até pouco tempo atrás, quando se falava em processador, pensava-se logo em uma unidade
indivisível em sua visão macro, composta de várias unidades funcionais trabalhando em conjunto
para um objetivo único comum, que era executar uma thread de código por vez. Nesta
concepção, cada processador era formado por um único núcleo de processamento, formado pelas
suas unidades funcionais.
Nos últimos tempos, porém, vêm ganhando visibilidade no mercado de hardware as
arquiteturas de processadores multicore. Estas arquiteturas nada mais são que uma evolução em
relação à arquitetura de um núcleo por processador, possibilitando que se tenham dois ou mais
núcleos dentro de um mesmo processador. Este aumento no número de núcleos foi possível
devido à tecnologia de fabricação de circuitos que evoluiu, possibilitando a miniaturização do
transistor. Deste modo, a fabricação de processadores com mais de um núcleo de processamento
se tornou uma solução comercial. Contudo, com as mesmas características das unidades
funcionais dos núcleos de processamento: capacidade de processamento de uma thread de código
por vez, no caso das SPE’s no processador Cell.
Em referência às arquiteturas multicore homogêneas muitas empresas como Intel, AMD e
SUN fabricaram seus processadores seguindo o conceito de multiplicação dos núcleos de
processamento iguais em um único processador.
O processador Cell BE foi a primeira arquitetura multicore heterogênea, onde os núcleos de
processamento são diferentes quanto à organização do processador.
O processador Cell BE é um microprocessador multicore heterogêneo com 1 elemento de
processamento principal (PPE – Power Processor Element) e 8 elementos de processamento
sinergísticos (SPE's- Sinergistic Processor Element) [5]. O PPE é um processador de propósito
geral e os SPEs são processadores dedicados, cada um formado por uma unidade de
processamento sinergístico (SPU) com 256 Kbytes de armazenamento local e um controlador de
fluxo de memória (MFC) [6].
Na figura3, apresentamos a arquitetura do sistema Cell BE. A arquitetura Cell Broadband
Engine é formada por um elemento de processamento principal (PPE) e 8 elementos de
processamento sinergísticos (SPE's) que trabalham de forma unificada. O elemento de
barramento de interconexão conecta os elementos de processamento com um subsistema de
comunicação de alta velocidade.
Figura 3: Arquitetura do Sistema Cell [2]
O Cell BE pode rodar até 10 threads simultaneamente, com até 200 GFlops de operações
sobre ponto flutuante de precisão simples, até 300 GB/s de velocidade de transferência interna e
até 25 GB/s de velocidade de acesso à memória.
O caminho para atingir esta alta capacidade de processamento atravessou várias barreiras. A
forma inovadora de ultrapassar estas barreiras levou a arquitetura Cell BE a um desenho
inusitado até então: a presença de núcleos diferentes dentro do mesmo processador trabalhando
de forma combinada.
As principais barreiras existentes hoje na evolução das arquiteturas de computadores são:
barreira de potência, barreira de memória e barreira de freqüência. A barreira de potência reflete
o fato de a dissipação de calor das tecnologias de transistor atuais ter chegado a níveis críticos
que atrapalham não só o bom funcionamento dos processadores mas também o uso eficiente da
energia elétrica. O processador Cell BE contorna a barreira de potência por ser uma arquitetura
heterogênea. Um processador heterogêneo chaveia menos de contexto e, por isso, gasta mais
tempo processando a aplicação fim e não o código de controle do sistema operacional,
aumentando a eficiência de entrega de instrução por consumo de energia. Além disso, o
multicore permite que se tenham núcleos mais simples que entregam uma capacidade conjunta
maior e, com núcleos mais simples, é possível a operação em alta freqüência com menores
voltagens, diminuindo também o problema de consumo de energia.
A barreira de memória reflete o fato de a freqüência de trabalho do processador ter aumentado
de forma muito mais rápida que a freqüência de trabalho das memórias DRAM. Com isso,
existem verdadeiros gargalos de processamento em programas que acessam muito a memória. Os
vários níveis de cache presentes nas arquiteturas atuais tentam amenizar este problema, mas a
barreira de memória é, ainda assim, um problema que impacta bastantes programas que
demandam alto poder de processamento. Em alguns casos até, os caches chegam a atrapalhar:
isso é relativamente comum em programas que demandam muitos cálculos e poucos acessos à
memória ou acessos a regiões esparsas da memória. Para atacar este problema, a arquitetura Cell
BE suporta carregamentos assíncronos entre os núcleos, através de streaming DMA. Além disto,
a memória é separada em três níveis: memória principal, Local Storage e Register File.
A barreira de freqüência reflete o fato de o simples aumento da freqüência de trabalho dos
processadores nas arquiteturas atuais causarem problemas físicos devido a interferências e
dissipação de calor que impedem maiores ganhos de velocidade com o aumento de pipelines, por
exemplo. A barreira de freqüência nitidamente impediu que nos últimos três anos o aumento de
freqüência dos processadores seguisse a Lei de Moore, que ditou este aumento desde meados da
década de 1980. Para atacar este problema, a arquitetura Cell BE com seus núcleos heterogêneos
possibilitou se tiver núcleos com funções mais especializadas e, portanto, com desenho mais
simples, permitindo-os operar em freqüências mais altas.
A seguir, vamos descrever os componentes mais importantes da arquitetura Cell Broadband
Engine.
2.1 PPE
O PPE é formado por um processador de propósito genérico PowerPC RISC de 64 bits capaz
de executar até duas threads simultaneamente com cache L1 de 32 KB para dados e 32 KB para
instruções e cache L2 de 512 KB para dados e instruções rodando a 3,2 GHz. Além disso, existe
suporte para instruções vetoriais VMX no PPE capaz de executar operações sobre inteiros e
pontos flutuantes de precisão simples. O conjunto com o processador PowerPC e as caches L1 é
conhecido como Power Processor Unit (PPU).
Como a PPU é um processador totalmente compatível com PowerPC, é possível rodar
programas compilados para este plataforma em Cell sem nenhum problema. O sistema
operacional também roda no núcleo PPU e possui extensões para conseguir administrar e
trabalhar de forma cooperativa com os núcleos SPEs. Porém, é importante frisar que o sistema
operacional não roda nos núcleos SPEs.
A PPU, no entanto, tem uma desvantagem em relação a outros PowerPC. Como ela está
embarcada dentro de um processador multicore mais complexo, seu projeto é mais simples que o
de outros PowerPC atual e, por isso, a eficiência de uma aplicação PowerPC rodando em um Cell
é consideravelmente menor que a eficiência desta mesma aplicação rodando em um processador
PowerPC de última geração.
2.2 SPE
Cada SPE possui uma Synergestic Processor Unit (SPU) e um Memory Flow Controller
(MFC), responsável pela movimentação e sincronização de dados e interface com o Element
Interconnect Bus (EIB).
A SPU é um processador in-order com unidades funcionais SIMD de 128 bits capaz de
processar inteiros e pontos flutuantes de precisão simples e dupla. Cada SPU tem uma memória
local para dados e instruções, o Local Store (LS), de 256 KB e um Register File com 128
registradores de 128 bits. A SPU tem 9 unidades funcionais distribuídas em 2 pipelines: para se
enviar 2 instruções para execução por ciclo é preciso que as instruções estejam alinhadas
alternando o pipeline que irão ocupar. Caso não seja possível enviar uma instrução para cada
pipeline, apenas uma instrução é enviada para execução por ciclo. Todas as instruções SPU
operam em cima de registradores. Não há instruções acessando diretamente o LS e não há cache.
Já o MFC é responsável pela movimentação e sincronização de dados e interface com o EIB.
Ele é responsável por todos os controles de todas as formas de comunicação do SPE: DMA,
mailboxes e sinais. Um dos conceitos por trás do MFC é as shopping lists, ou seja, o MFC torna
possível que o programador especifique quantos e quais dados buscar num determinado
momento. O programador pode buscar todos os dados que irá utilizar no processamento SPU de
uma vez só, eliminando a sobrecarga que seria causada, por exemplo, pelo uso de cache, que
buscaria dado por dado na memória principal quando ele fosse acessado a primeira vez, pelo
menos. Além disto, o MFC é capaz de processar e executar comandos de DMA em paralelo com
o fluxo de execução da SPU. Ou seja, práticas como double-buffering e multi-buffering fazem
com que seja possível buscar o próximo dado a ser processado na SPU enquanto está
processando o dado atual. O que torna um aumento considerável de performance de
processamento do processador Cell.
O LS é isolado da memória principal, ou seja, ele não se comporta como um cache e não
aceita tags nem prefetch. Não é necessária tradução de endereços para o acesso ao LS já que o
sistema operacional multiusuário roda apenas na PPU. Mas é importante dizer que é possível
mapeá-lo no espaço de endereçamento da memória principal de forma que o PPE possa enxergar
esta memória como se ela fosse parte da memória principal. No entanto, mesmo assim, todos os
acessos ao Local Store são feitos por intermédio do MFC. O que acontece é que, quando este
mapeamento está ligado, o PPE acessa o Local Store de forma transparente com a ajuda do MFC.
No entanto, mesmo com este mapeamento ligado, uma SPU continua só tendo acesso à sua
própria Local Store e continua responsável pela coerência de sua memória. Ou seja, caso ela
queira acessar a um dado na memória principal ou no Local Store de outra SPU, ela terá que
fazer isso através dos comandos providos pelo MFC. Por último, apesar de o LS não se
comportar por padrão como um cache, é possível adicionar este suporte através de um cache
gerenciado por software.
2.3 EIB
O Element Interconnect Bus (EIB) é o elemento de comunicação entre os 9 núcleos de um
processador Cell BE e os barramentos externos de memória e I/O. Ele é formado por uma
estrutura de quatro anéis conectando os vários elementos dentro do processador Cell e pode
chegar a uma taxa de transferência interna de até 300 GB/s. Dois destes anéis transferem dados
no sentido horário e dois deles no sentido anti-horário. Os quatro anéis trabalham de forma que
as transferências que estejam ocorrendo em um deles não interfiram eventuais transferências que
estejam ocorrendo simultaneamente em algum dos outros anéis. Além disso, o árbitro central do
barramento permite que até três transferências simultâneas ocorram no mesmo anel desde que
elas não necessitem utilizar o mesmo pedaço de caminho dentro do anel.
3. Cell Broadband Engine Roadmap
Como vimos o processador Cell consegue entregar um alto poder de processamento. No
entanto, existem planos para expansão deste modelo.
Além da evolução óbvia de se tentar colocar mais núcleos PPE e SPE dentro de um mesmo
processador, também existem dois outros pontos que tendem a evoluir no futuro próximo.
A primeira delas é relacionada ao suporte a operações vetoriais de ponto flutuante de precisão
dupla nas SPUs. Apesar de tais operações já serem possíveis hoje, elas não são totalmente
pipelined e parte delas é feita por emulação em software. Isto ocorre porque não há na SPU uma
unidade funcional capaz de executar em hardware operações de ponto flutuante de precisão
dupla. Basicamente a arquitetura não tem este suporte porque, para o propósito original do
processador Cell BE que era atender à demanda do mercado de console de jogos equipando o
PlayStation 3, este tipo de operação não é importante pois não é demandada tamanha precisão em
software de jogos. No entanto, para as novas aplicações para as quais o Cell está sendo apontado,
este tipo de precisão pode ser importante. Desta forma, existe a perspectiva de se ter no futuro
um Cell BE equipado com SPUs que tenham suporte completo em hardware para operações com
ponto flutuante de precisão dupla.
Além disso, outra questão importante na evolução do Cell é a possibilidade de se colocar na
PPU um processador PowerPC de última geração, com capacidade de processamento equivalente
à de um processador PowerPC monocore ou multicore homogêneo.
Na figura 4 mostramos uma perspectiva de evolução possível para a arquitetura Cell BE:
Figura 4: Perspectiva de evolução da arquitetura Cell BE nos próximos anos (Referência
IBM).
4. Cell SDK 2.1
O Cell SDK 2.1 provê suporte ao desenvolvimento de aplicações para arquitetura Cell em
outras plataformas através de um ambiente de cross-development. O ambiente usado para o
desenvolvimento é chamado de host e o ambiente target, neste caso, é uma máquina Cell ou um
simulador de Cell.
Como ambientes host são suportados: x86, x86_64, ppc64 e Cell rodando Fedora Core 6.
Alguns dos componentes do Cell SDK 2.1 são:
Compiladores e ferramentas GNU PPU e SPU (gcc, ld, combined gdb);
Compiladores XL C/C++ PPU e SPU (incluindo suporte a auto-SIMD);
IBM Cell System Simulator;
SPU Timing;
FDPR-Pro;
Cell IDE, baseado em Eclipse/CDT;
Bibliotecas MASS/V (para PPU e SPU) e SIMD Math;
Várias bibliotecas e exemplos com um ambiente pré-configurado para o build de
aplicações para Cell.
O Cell SDK 2.1 pode ser baixado do IBM AlphaWorks e do Barcelona Supercomputing Center.
É interessante notar que o simulador de Cell que acompanha o Cell SDK 2.1 torna possível
que o desenvolvimento de aplicações para Cell seja feito de forma completa mesmo que não se
tenha uma máquina com processador Cell BE disponível. A IBM Cell System Simulator é capaz
de simular a funcionalidade de todos os componentes da arquitetura Cell BE e é capaz de simular
também os SPEs e as transferências de DMA temporalmente, de forma que é possível obter,
inclusive, informações valiosas de performance da execução de uma aplicação usando o
simulador. Muitas vezes, as informações captadas pelo simulador seriam muito difíceis de se
obter mesmo usando um hardware real.
Outro ponto importante e que pode ajudar bastante principalmente os iniciantes na
programação para Cell é o Cell IDE. A interface gráfica fornecida já tem integração com os
compiladores e outras ferramentas necessárias para o build de projetos Cell, inclusive com
suporte para build automático de aplicações que rodam tanto no PPE quanto no SPE que serão
comentadas nas seções seguintes. O Cell IDE fornece também integração com o simulador e
deploy automático de aplicações em um simulador local ou remoto ou mesmo em uma máquina
Cell real, com capacidade de debug remoto da aplicação.
5. Modelos de Programação para o Cell
Devemos nos perguntar antes de iniciar o processo de programação neste novo paradigma de
programação multicore para Arquitetura Cell Broadband Engine: o que é necessário para o
modelo de programação no Cell BE?
Vejamos algumas características importantes para este modelo de programação:
Capacidade de processamento massivamente paralelo: devem-se explorar todos os 18
dispositivos assíncronos do Cell BE através de delegação de tarefas ou computação
paralela, como, por exemplo, intercalando transferência de dados através de DMA com
computação.
A distribuição do código deve levar em conta a especialização de cada núcleo: código de
controle para o PPE e código de processamento massivo de dados para os SPEs.
Vetorização: é importante explorar o paralelismo de dados.
Largura de banda de alto desempenho.
Recursos distribuídos.
Programador possui uma sistemática da arquitetura e um custo efetivo do Framework
para aplicar os recursos do Cell a uma classe específica de aplicações.
Modelo de programação suporta vários construtores de linguagens, runtime, bibliotecas,
ou Frameworks orientados a objeto.
Focando-se em como uma aplicação pode ser particionada entre os elementos de
processamento (PPE e SPE's) existem algumas considerações relevantes na programação do Cell
[7]:
1. Processamento baseado em carregamentos (como em uma arquitetura load/store).
2. Movimentação de dados e código via DMA (Direct Memory Access).
3. Estrutura do programa.
4. Fluxo de dados.
5. Carga do barramento.
É sempre importante lembrar que um arquiteto não deve começar o desenvolvimento de
aplicações para Cell BE pensando nestas características a partir de suas premissas mais básicas.
Já existe uma pilha de software completa disponível para a plataforma Cell BE cujo propósito é
justamente facilitar o trabalho das pessoas escrevendo aplicações para esta plataforma. O que
torna mais fácil a aderência de um programa às características acima e, conseqüentemente,
tornando mais fácil a obtenção de bons ganhos em capacidade de processamento. Na figura 5
mostramos a pilha de software já existente no ambiente de desenvolvimento de aplicações para
processadores Cell BE.
Figura 5: Pilha de software para plataforma Cell BE.
Com a devida atenção a estas características e com o seu uso adequado é possível se obter
ganhos super lineares no poder de processamento em relação a arquiteturas convencionais.
O processador Cell BE suporta uma variedade imensa de modelos de programação. Segundo
J. A. Kahle et al. [9], em seu artigo de introdução à arquitetura Cell no IBM JRD (Journal of
Research and Development), os modelos de programação são:
5.1. Modelo “Function Offload”
Neste modelo, a aplicação principal é executada na PPE, invocando funções otimizadas que
rodam em uma ou mais SPE's. Atualmente, o programador identifica estaticamente quais as
funções podem ser executadas na PPE, e quais são executadas na SPE.
5.2. Modelo de Dispositivo Extendido
O modelo de dispositivo extentido é um tipo especial da função “offload”. A SPE prove a
função previamente disponibilizada pelo dispositivo, atuando como interface inteligente para o
dispositivo externo. Este modelo utiliza as técnicas de “Mailboxes” ou mapeamento de memória
da SPE acessível aos registradores, entre a PPE e a SPE através de comando / resposta FIFO.
5.3. Modelo de Aceleração Computacional
Este modelo é centrado na SPE que prove mais granularidade e uso integrado das SPE's por
uma aplicação ou ferramentas de programação. O software PPE atua como controle e
disponibiliza um sistema de serviço para o software SPE. Técnicas de paralelização podem ser
utilizadas para distribuir o trabalho acerca de múltiplas SPE's, executando em paralelo.
5.4. Modelo Stream
Neste modelo, a SPE suporta passagem de mensagem da PPE para SPE. Existe um fluxo
contínuo de dados enfileirados, sendo executados em paralelo pelas múltiplas SPE's, chamadas
também de núcleos de processamento (kernel computacional). No caso do modelo de streaming,
os núcleos de processamento em geral são todos iguais e os dados são divididos entre eles e
processados em paralelo.
Outra alternativa que pode ser usada é relacionada a este modelo, fazendo com que os núcleos
computacionais diferentes atravessem um determinado dado através de todos os núcleos. Neste
caso ter-se-ia um modelo pipeline.
5.5. Modelo de Memória Compartilhada
Neste modelo, o acesso a dados são feitos de forma randômica através de seus endereços. Há
suporte a variáveis compartilhadas. Através do mecanismo de bloqueio, vários programas SPE's
podem acessar objetos da memória compartilhada localizados no espaço de endereçamento
efetivo. O Centro de Super Computação em Barcelona (BSC), desenvolveu um compilador que
suporta extensões parecidas com OpenMP [10]. A diferença básica na programação é que o
OpenMP padrão usa variável global e o compilador OpenMP para Cell usa variável privada
devido a existência das SPE's.
5.6. Modelo “Asymetric Thread Runtime”
Neste modelo, os processos podem ser escalonados entre a PPE e as SPE's, similar a uma
arquitetura SMP (Symetric Multiple Processing) convencional. Várias políticas de escalonamento
podem ser aplicadas para os dois processos, seja PPE ou SPE, para otimizar o desempenho e a
utilização do uso das SPE's.
5.7. Outros modelos
É importante lembrar que além dos modelos vistos acima, outro modelos podem ser aplicados
também. Por exemplo, todos os modelos já disponíveis para programação em arquiteturas
monocore ou em arquiteturas com suporte a Simultâneos Multi-threading (SMT) podem ser
aplicados de forma isolada a programas rodando no PPE. Da mesma forma, todos os modelos
convencionais de programação paralela podem ser aplicados à PPE e suas SPEs.
Outra alternativa muito usada é o encapsulamento de funções críticas em bibliotecas que
rodam códigos nas SPEs, mas que são ligadas a programas PPE já que esta característica é
permitida pela plataforma de software da arquitetura Cell BE. Desta forma, os desenvolvedores
não precisam reescrever seus códigos que já rodam em PowerPC e, para que o código rode de
forma otimizada na plataforma Cell BE basta que ele seja novamente ligado à biblioteca com
código otimizado para aproveitar o paralelismo provido pela arquitetura. Um exemplo prático de
uso deste paradigma é o desenvolvimento de jogos, onde boa parte do trabalho é delegada a uma
biblioteca de OpenGL, por exemplo. Neste caso, o mesmo jogo é capaz de rodar em um
processador Cell BE ou em outro processador, bastando para tal que o código seja recompilado
utilizando a biblioteca otimizada de OpenGL para uma determinada arquitetura.
É interessante ter em mente que o núcleo SPE é capaz de processar apenas uma thread por
vez, de forma que se o programador quiser simular algo parecido com várias threads executando
em um núcleo SPE ele terá que programar também um pequeno kernel no SPE que faça o
escalonamento de suas tarefas.
É importante lembrar também que os programas SPE podem ocupar apenas o espaço físico de
256 KB provido pelo Local Store para dados e instruções. Caso haja necessidade de programas
maiores que 256 KB no SPE, o programador da aplicação terá que utilizar técnicas de
desenvolvimento de aplicativos que o possibilitem carregarem apenas partes do código de cada
vez nas SPEs, por exemplo, pelo uso de overlays ou apenas parte dos dados a serem processados
por vez, como, por exemplo, através do uso de técnicas de software cache. Estas duas técnicas,
overlays e software cache, são suportadas por padrão pelo Cell BE SDK, que provê em sua pilha
de software bibliotecas que facilitam o uso destas funcionalidades.
De forma geral, os modelos de programação servem de um bom guia para se iniciar o desenho
de aplicações para plataformas Cell BE. No entanto, é bom sempre lembrar que o que vimos são
apenas linhas mestras: misturar modelos de programação pode ser necessário e algumas vezes,
até, aplicações específicas exigem modelos de programação diferentes dos vistos aqui. O
importante é escolher o modelo correto, pois isso influenciará diretamente no tempo de
desenvolvimento e na eficiência da aplicação final.
Capítulo 2: Programando com Cell SDK 3.0
1. Introdução
Como estudamos, a arquitetura Cell Broadband Engine é considerada heterogênea devido
aos nós de processamento ser heterogêneos. O elemento de processador Power (PPE) é baseado
no processador PowerPC com conjunto de instruções extendidas SIMD / Vetoriais através do
VMX. Já o elemento processador sinergístico (SPE) executa instruções SIMD de forma direta.
Portanto, como o conjunto de instruções é diferente, para cada programa desenvolvido em PPE
ou SPE, existe um compilador especifico para ambos [11].
Um dos objetivos dos compiladores é explorar novos estilos de programação. O
compilador oferece vetorização automática, mas também possui características internas para dar
acesso direto à funcionalidade SIMD dos processadores. Os compiladores tanto para PPE quanto
para unidades SPE são altamente otimizados para as seguintes linguagens: C, C++, Fortran [12,
13].
O paralelismo heterogêneo é a chave para a base do compilador. Os co-processadores
(SPE’s) não executam o mesmo conjunto de instruções. A PPE é baseada na arquitetura
PowerPC, mas os SPE’s não, gerando a necessidade de tratamento especial do compilador tais
como: não há suporte a predição de desvio de hardware, arquitetura não orientada a múltiplos
processos, único nível de memória. Este tratamento do compilador faz com que ele contenha
compiladores para PPE e SPE.
O compilador para plataforma Cell BE introduz algumas especificações OpenMP e outras
do compilador IBM XL. Foi desenvolvido o compilador XL C especialmente para arquitetura
Cell, disponível para avaliação no AlphaWorks [14].
Atualmente, o ambiente de desenvolvimento para plataforma Cell chegou a sua versão
estável chamada “Software Development Kit for Multicore Acelleration version 3”. Tanto
hardware quanto o software passaram por inúmeras versões até chegar à sua versão estável.
Para entendermos os modelos de programação para plataforma Cell, devemos conhecer os
recursos de programação. A princípio, temos:
Recursos Computacionais:
2. 1PPE e 8 SPE cores;
3. Máquina SIMD;
4. 256 KB para Armazenamento Local (Código + Dados).
Recursos de Comunicação:
Barramento de Interconexão de 98B/ciclo;
SPE DMA;
Granularidade e latência de DMA;
Sincronização
Neste capítulo, apresentaremos como desenvolver um código para Cell Broadband Engine,
introduzindo o ambiente de desenvolvimento provido pelo Cell SDK 3.0 e o IDE baseado em
Eclipse para o Cell SDK. Demonstraremos como criar projetos Hello_SPU e Hello_PPU, como
compilar e debugar a aplicação no Cell System Simulator.
Neste novo ambiente de desenvolvimento Cell SDK 3.0 tiveram várias novidades nos
procedimentos de instalação através do gerenciar de pacotes SDK – Pirut GUI [15] e do comando
YUM, bem como adição e atualizações dos compiladores para Cell (como por exemplo:
FORTRAN, Ada, XL/C++). Além de o sistema operacional ser baseado na distribuição do Linux
Fedora 7 para pesquisadores e para dar continuidade a desenvolvimento de software open-source.
Em outubro deste ano (2007), será disponibilizado o suporte do Cell SDK 3.0 para
desenvolvimento comercial com suporte Linux Red-Hat 6.
2.1 Requisitos de Hardware / Software
Para iniciarmos o desenvolvimento dos projetos no Eclipse para o Cell SDK 3.0, devemos
checar se todos os requisitos de hardware e software estão devidamente instalados e configurados
no sistema.
O Cell SDK 3.0 suporta as seguintes plataformas: x86, x86_64, PPC64, IBM Blade QS20,
IBM Blade QS21. É recomendável que se tenha no mínimo 5GB de espaço livre em disco e 1GB
de RAM para instalar todos os pacotes e ferramentas de desenvolvimento.
Com relação aos requisitos de software, há vários procedimentos para instalação do Fedora
7, instalação de pacotes previa (preparação para instalar o Cell SDK 3.0) e dependências de
software.
No minicurso em questão, não entraremos em detalhes de instalação de hardware e
software. Forneceremos este material através do material do minicurso (DVD) e pelo Portal
CellBR [16] que possui a missão de divulgar a tecnologia Cell, promovendo o desenvolvimento
de software open-source, ferramentas de desenvolvimento, aplicações para processamento de
imagens e pesquisas. O grupo PAD em parceria com a IBM Brasil está desenvolvendo o YUM
Server para armazenar todos os pacotes RPM's para o Brasil sem a necessidade de realizar
download do BSC.
Na instalação do Fedora 7, recomenda-se a não instalação do Eclipse Fedora, e providenciar a
versão 2.2 da IDE Eclipse através do download na Web site do Eclipse org. [17]. Para o suporte
à criação de projetos no ambiente C/C++, a instalação do CDT 3.1 deve ser instalada. Outra
recomendação importante é fazer download do Java SDK 1.4.2 apenas do site da SUN ou da
IBM e configurá-lo adequadamente no sistema para a versão pré-instalada do Fedora 7 não
interfira no sistema.
2.2 Criando Projetos no Eclipse
Para rodar o Eclipse 3.2, basta clicar em aplicações na barra de ferramentas, programação,
eclipse. Ou simplesmente digitar na linha de comando: /opt/cell/ide/eclipse
> ./eclipse
Para utilizar o Cell SDK 3.0, temos que checar em atualizações de software se o Eclipse
Platform Runtime e o CDT estão devidamente instalados.
Inicialmente, modificamos a perspectiva do ambiente de desenvolvimento para criar
projetos em C/C++, como apresentado na figura a seguir:
Figura 06: Modificar a perspectiva do Ambiente de Desenvolvimento
Inicialmente, apresentaremos a criação de um projeto SPU com o make gerenciado. Caso o
usuário deseje desenvolver seu próprio makefile, poderá consultar o makefile padrão do exemplo
“simple” do tutorial do próprio Cell SDK 3.0 no seguinte diretório:
/opt/cell/sdk/src/tutorial/simple
Figura 07: Criando um novo Projeto com C Managed Make
Nomeamos o nosso projeto de SPU e selecionamos um compilador para SPU executável.
Figura 08: Selecionar o Cell SPU executável
Finalizando a criação do Projeto SPU, temos de configurar as propriedades do projeto como:
1. Inserir o caminho do diretório
Veja na figura 09, o caminho do diretório a ser inserido na propriedade do projeto.
/opt/cell/sysroot/opt/cell/sdk/usr/spu/include
Figura 09: Caminho do Diretório do include da SPU
Neste momento criamos um arquivo hello_spu.c escrevendo o seguinte código:
#include <stdio.h>
#include <profile.h>
int main(unsigned long long id)
{
//prof_clear();
//prof_start();
printf("WSCAD2007: Hello World (0x%llx)n", id);
//prof_stop();
return 0;
}
Salvando o código, o projeto SPU é compilado.
Dando continuidade, criamos o projeto PPU com o SPU embutido. Selecionamos novo projeto
com o compilador Cell PPU executável e o SPU embutido.
Figura 10: Criação do Projeto PPU
Quanto às propriedades do Projeto PPU, iremos configurar os seguintes parâmetros:
1. A entrada da PPU GNU 32 bit Embed SPU (/root/workspace/SPU/hello_spu)
2. Inserir o link para biblioteca -libspe2
Na figura 11, apresentamos como configurar o caminho para o Input do PPU link. E na figura 12,
como inserir a biblioteca libspe2.
Figura 11: Inserir o Input do PPU link
Figura 12: Inserir a biblioteca libspe2
A próxima etapa é escrever o código para PPU, descrito a seguir:
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <libspe2.h>
#include <pthread.h>
extern spe_program_handle_t SPU;
#define SPU_THREADS 8
void *ppu_pthread_function(void *arg) {
spe_context_ptr_t ctx;
unsigned int entry = SPE_DEFAULT_ENTRY;
ctx = *((spe_context_ptr_t *)arg);
if (spe_context_run(ctx, &entry, 0, NULL, NULL, NULL) < 0) {
perror ("Failed running context");
exit (1);
}
pthread_exit(NULL);
}
int main()
{
int i;
spe_context_ptr_t ctxs[SPU_THREADS];
pthread_t threads[SPU_THREADS];
/* Create several SPE-threads to execute 'SPU'.
*/
for(i=0; i<SPU_THREADS; i++) {
/* Create context */
if ((ctxs[i] = spe_context_create (0, NULL)) == NULL) {
perror ("Failed creating context");
exit (1);
}
/* Load program into context */
if (spe_program_load (ctxs[i], &SPU)) {
perror ("Failed loading program");
exit (1);
}
/* Create thread for each SPE context */
if (pthread_create (&threads[i], NULL, &ppu_pthread_function, &ctxs[i])) {
perror ("Failed creating thread");
exit (1);
}
}
/* Wait for SPU-thread to complete execution. */
for (i=0; i<SPU_THREADS; i++) {
if (pthread_join (threads[i], NULL)) {
perror("Failed pthread_join");
exit (1);
}
/* Destroy context */
if (spe_context_destroy (ctxs[i]) != 0) {
perror("Failed destroying context");
exit (1);
}
}
printf("nThe program has successfully executed.n");
return (0);}
A biblioteca libspe2.h é a referência para a SPE Runtime Management Library que está na versão
2.2 no SDK 3.0. Mais informações sobre como usar esta biblioteca estão no documento "SPE
Runtime Management Library Version 2.2 Draft" [17] que está em /opt/cell/sdk/docs/lib depois
que o SDK 3.0 é instalado.
A estrutura de dados spe_program_handle_t guarda as informações a respeito de um
programa SPE que é encapsulado dentro de um programa PPE.
#define SPU_THREADS 8
void *ppu_pthread_function(void *arg) {
Está função é criada para ser a função executada nas threads criadas com a biblioteca
pthreads da PPE. O único propósito dela neste programa exemplo é iniciar a execução das
threads SPE. É necessária a criação destas threads PPE porque sempre que uma thread SPE é
criada por um programa PPE, a thread do programa PPE fica bloqueada na chamada
spe_context_run. Desta forma, se você estiver desenvolvendo um programa PPE e SPE em que a
parte PPE crie e gerencie diversas threads SPEs, você vai ter que criar uma thread PPE para
gerenciar cada uma das threads SPE criadas para que o programa PPE não fique travado na
criação da primeira thread SPE. Você pode pensar em uma analogia que quando você faz uma
chamada spe_context_run, a thread sendo executada transforma de uma thread PPE para uma
thread SPE. Se você não tiver criado uma thread PPE específica para se "transformar" em uma
thread SPE, seu programa PPE inteiro se "transformará" apenas em uma única thread SPE e você
não terá oportunidade de criar outras threads SPE até que a primeira termine e retorne.
spe_context_ptr_t ctx;
Esta estrutura de dados spe_context_ptr aponta para o contexto de uma SPE. O contexto de
uma SPE é formado pelo seu Local Store e pelo seu MFC problem state.
unsigned int entry = SPE_DEFAULT_ENTRY;
ctx = *((spe_context_ptr_t *)arg);
if (spe_context_run(ctx, &entry, 0, NULL, NULL, NULL) < 0) {
A chamada spe_context_run pede ao sistema operacional que ele aloque uma SPE para
rodar o programa SPE carregado no contexto indicado e inicie seu processamento.
perror ("Failed running context");
exit (1);
}
pthread_exit(NULL);
}
int main()
{
int i;
spe_context_ptr_t ctxs[SPU_THREADS];
pthread_t threads[SPU_THREADS];
/* Create several SPE-threads to execute 'SPU'.
*/
for(i=0; i<SPU_THREADS; i++) {
/* Create context */
if ((ctxs[i] = spe_context_create (0, NULL)) == NULL) {
A função spe_context_create cria um contexto SPE que poderá ser, posteriormente,
escalonado em uma SPE física.
perror ("Failed creating context");
exit (1);
}
/* Load program into context */
if (spe_program_load (ctxs[i], &SPU)) {
A chamada spe_program_load carrega um programa SPE em um contexto já criado para
que, quando este contexto for escalonado para execução, a aplicação carregada nele seja
executada.
perror ("Failed loading program");
exit (1);
}
/* Create thread for each SPE context */
if (pthread_create (&threads[i], NULL, &ppu_pthread_function, &ctxs[i])) {
Criação das threads PPE que executarão o código da função ppu_thread_function que,
como já explicado, é o código que irá chamar spe_context_run para escalonar os contexto criados
em SPEs físicas.
perror ("Failed creating thread");
exit (1);
}
}
/* Wait for SPU-thread to complete execution. */
for (i=0; i<SPU_THREADS; i++) {
if (pthread_join (threads[i], NULL)) {
Espera-se que cada thread PPE retorne (o que implicitamente significa que cada thread SPE
também terá finalizado seu trabalho, já que as threads PPE ficaram bloqueadas na chamada
spe_context_run presente em ppu_thread_function).
perror("Failed pthread_join");
exit (1);
}
/* Destroy context */
if (spe_context_destroy (ctxs[i]) != 0) {
spe_context_destroy destrói os contextos criados e libera a memória usada por eles.
perror("Failed destroying context");
exit (1);
}
}
printf("nThe program has successfully executed.n");
return (0);
}
No ambiente Cell, iremos criar um simulador local e configurá-lo. O simulador pode
rodar em diversos ambiente como: janela de controle, TCL console, Linux console e diretório de
trabalho.
Figura 12: Propriedades do Simulador Cell Local
Pode ser que o simulador não reconheça a configuração de rede (quando configurado para
DHCP). Para criar o simulador Cell no ambiente Eclipse, é preciso configurar o DNS da rede.
Depois de rodar o simulador, é preciso depurar a aplicação, criando um novo “Cell
C/C++ Target Application”, como apresentado na figura 13 e 14:
Figura 13: Ambiente de depuração
Figura 14: Criação do novo C/C++ Cell Target Application
Na configuração desta aplicação, normalmente já vem selecionado o nome do projeto
selecionado para depuração. O próximo passo, é inserir o projeto executável como demonstrado
na figura 15:
Figura 15: Seleção do projeto executável
A seguir, na figura 16, configuramos o Debugger para Cell BE gdbserver gdb/mi e incluimos o
caminho do diretório para o servidor, localizado em /opt/cell/toolchain/bin/ppu-gdb. Quando
acionamos o Debug o servidor gdbserver é chamado através do endereço IP configurado para
HOSTNAME.
Figura 16: Configuração do Debugger
Neste diretório indicado para selecionar o servidor gdbserver há várias opções de
servidores para debuggers específicos para PPU e SPU, e também quanto ao tipo de arquitetura.
Para ajudar o processo de Debug, no Cell SDK 3.0, temos a ferramenta de desempenho de
Debug (“Performance Debugging Tool”) que apresenta um visualizador da saída do trace. Outra
ferramenta de desempenho (FDPR-Pro) externa ao simulador é interessante por otimizar a
execução dos projetos PPU/SPU executável. Estas duas ferramentas são estudadas em detalhes
no guia do programador [18].
Para finalizar esta demonstração, apresentaremos uma análise de desempenho fazendo uso
do “dynamic profiling”. Esta ferramenta será utilizada no código SPU. Observando o código
escrito, destacamos três linhas comentadas para as funções: prof_clear(), prof_start(), e
prof_stop(). Descomentamos estas linhas e salvamos o código. E depois recompilamos
novamente o projeto PPU.
Na janela do simulador, podemos iremos modificar o “SPU mode” para o modo pipeline,
como apresentado na figura 17:
Figura 17: Modificar o SPUmode
Finalizando este procedimento, rodamos a aplicação PPU através: Run -> Run History ->
PPU. Agora, podemos analisar as estatísticas na janela do simulador no SPE0.
Figura 18: Visualização das Estatísticas do Simulador
No capítulo 4, estas ferramentas serão apresentadas com mais detalhes
Capítulo 3: Programando para Cell BE: DMA, Mailboxes e
SIMD
1. Introdução
Como vimos anteriormente, a arquitetura Cell BE provê uma série de mecanismos para
orquestrarmos os diferentes elementos de processamento paralelo disponíveis. Estes mecanismos
de coordenação são essenciais no desenho de plataformas multicore pois são eles que permitem o
controle das concorrências entre as diversas tarefas sendo executadas nos diversos elementos de
processamentos da arquitetura. No caso da arquitetura Cell BE, os principais mecanismos de
sincronização existentes são os Mailboxes e as transferências de dados por DMA. Outros
elementos existentes como eventos e sinais não serão discutidos neste mini-curso introdutório.
Além disso, a arquitetura Cell BE fornece unidades de execução vetorial em todos os seus
elementos de processamento. É importante que alguém programe para esta arquitetura tenha
ciência disto e tente usar estas unidades de execução vetorial sempre que possível. No caso de
programas PPE o uso de instruções vetoriais pode trazer ganhos consideráveis pelo uso do
paralelismo de dados. Já nos programas SPE, o uso de instruções vetoriais é praticamente
mandatório, já que este núcleo foi projetado como um elemento de processamento
intrinsecamente vetorial.
Nas seções seguintes, apresentaremos detalhadamente destes três elementos básicos da
programação para a arquitetura Cell BE e explicar um exemplo prático de multiplicação de
matrizes fornecido junto com o Cell BE SDK.
2. DMA
Antes de falamos sobre DMA propriamente dito, precisamos entender um pouco melhor
os Memory Flow Controllers (MFC). Todos os elementos de comunicação disponibilizados pela
arquitetura Cell BE são controlados, em última instância, pelos MFCs de cada SPE. Estes MFCs
funcionam praticamente como núcleos extras da arquitetura pois são capazes de executar suas
atividades de comunicação de forma paralela à execução de código das SPEs.
Para se iniciar qualquer uma das formas de comunicação (DMA, mailbox, sinais e
eventos), é necessário que sejam gerados comandos para o MFC. Estes comandos podem ser
gerados basicamente de duas formas: um código rodando no SPE executa uma série de escritas
e/ou leituras no seu canal de instruções; ou um código rodando no PPE ou em outros dispositivos
faz uma série de stores e/ou loads em registradores do MFC mapeados em memória.
Os comandos do MFC são enfileirados em duas filas independentes: MFC SPU
Command Queue, para os comandos associados à SPU iniciados pelo canal de controle; e MFC
Proxy Command Queue, para comandos iniciados pelo PPE ou por outro dispositivo através dos
registradores mapeados em memória. É interessante dizer ainda que há suporte a alguns
comandos atômicos no MFC.
O DMA é o meio existente para transferir grandes quantidades de dados e instruções de
forma eficiente entre o LS e a memória principal. No entanto, pode-se usar DMA para a
transferência de pequenas quantidades de dados também.
Comandos de DMA nada mais são que comandos de MFC que transferem dados, sendo
que a direção da transferência é sempre em relação ao SPE mesmo que o comando MFC tenha
sido gerado através de escritas e/ou leituras nos registradores do MFC mapeados em memória
pelo PPE ou por outro dispositivo. Ou seja, quando estamos transferindo um dado para o SPE (da
memória principal para o LS), o prefixo do comando de DMA é get. Já quando estamos
transferindo um dado do SPE (do LS para a memória principal), o prefixo do comando de DMA
é put.
Apesar de ser possível iniciar um DMA através de diversas escritas e/ou leituras nos
canais de instrução do SPE ou nos registradores mapeados em memória do MFC, o Cell SDK 2.1
fornece uma série de macros de mais alto nível que agrupam estas escritas e/ou leituras de forma
a facilitar a vida de quem precise realizar DMAs no Cell. Estes macros são definidos no arquivo
spu_mfcio.h. Por exemplo, existem macros já definidas para iniciar um get ou um put através
de DMA passando apenas as regiões de memória de interesse, basicamente.
Sempre que possível, os DMAs devem ser iniciados dos SPEs pois assim ter-se-á uma
maior performance nas transferências. Existem basicamente dois motivos para esta melhor
performance de DMAs iniciados pelo SPE. Primeiro porque independente de onde o DMA esteja
sendo criado, ele vai ser executado pelo MFC do SPE. Ou seja, se o PPE estiver iniciando um
DMA, na verdade ela vai requisitar os dados ao MFC e o MFC irá realizar a transferência.
Quando uma SPU requisita um DMA ao MFC, ele o faz através de sucessivas leituras/escritas
nos canais de instrução do SPE, cujo acesso é mais rápido que o dos registradores do MFC
mapeados em memória utilizados pelo PPE para requisitar o mesmo DMA ao MFC. Depois
porque existe um maior número de SPEs que de PPE. Se todos os DMAs forem originados pelo
PPE, haverá um gargalo neste ponto. Já se eles forem originados dos SPEs, o trabalho de
preparação do DMA será distribuído nos recursos disponíveis no processador Cell.
Como já visto, o MFC é capaz de processar e executar comandos de DMA em paralelo
com o fluxo de execução da SPU. Ou seja, práticas como double-buffering e multi-buffering
fazem com que seja possível buscar o próximo dado a ser processado na SPU enquanto se está
processando o dado atual, aumentando ainda mais a performance de processamento do
processador Cell.
Algo extremamente importante de ser lembrado no caso dos DMAs é que os comandos de
DMA não necessariamente são executados em ordem. Para assegurar a ordem de execução das
requisições DMA o MFC disponibiliza dois tipos de sincronizações: fence e barrier. Os
comandos fenced são aqueles em que todos os comandos de DMA antes dele com o mesmo tag
group devem terminar antes deste, e comandos executados depois dele também podem terminar
antes dele. Já os comandos barrier são aqueles em que ele e todos os comandos de DMA depois
dele com o mesmo tag group não são executados até que todos os comandos anteriores com este
tag group estejam completos.
Figura 19 – fence e barrier nas transferências de DMA (Referência IBM).
As transferências de DMA podem ser de 1, 2, 4, 8, 16 e múltiplos de 16 bytes, até 16 KB
por transferência. Para que os DMAs possam ocorrer, os dados a serem transferidos devem estar
naturalmente alinhados se tiverem 1, 2, 4, 8 ou 16 bytes. Para transferências de tamanhos
múltiplos de 16 bytes o alinhamento deve ser de, no mínimo, 16 bytes. Para melhor eficiência na
transferência por DMA, os dados devem estar alinhados em 128 bytes já que este é o tamanho
das linhas de cache no PPE.
Os tag groups que identificam e agrupam as transferências de DMA variam de 0 a 31 (5
bits). O mesmo identificador pode ser usado em quantos comandos quanto se quiser. Este tag
group também pode ser usado para se saber o status ou para esperar a finalização do comando de
DMA, já que os comandos não são bloqueantes.
O Cell BE também tem suporte à execução de listas de DMA. Estas listas de DMA são
uma forma eficiente de se fazer transferência de dados que não sejam contíguos da ou para a
memória principal. Num mesmo comando de DMA é possível especificar a lista de regiões de
serão transferidas e, através de uma funcionalidade scatter-gather, uma lista com até 2 K
requisições pode ser transferida no mesmo comando de DMA.
Apesar de sempre falarmos que as transferências de DMA são feitas sempre entre
memória principal e LS, também é possível transferências de dados por DMA entre SPEs, desde
que esteja ativo o mapeamento dos LSs no espaço de endereçamento da memória principal. Desta
forma, onde colocar um endereço da memória principal nos comandos de DMA pode-se colocar
um endereço de memória principal que esteja mapeado para um LS de outro SPE. Existem
artifícios internos à arquitetura que tornam possível para o PPE calcular o endereço mapeado na
memória principal de uma variável de um LS. Este endereço pode ser passado por exemplo por
mailbox para outro SPE que pode, então, fazer uma transferência de DMA utilizando este
endereço mapeado no LS do primeiro SPE como origem ou destino.
3. Mailboxes
Os Mailboxes são filas para trocas de mensagens entre os diversos componentes ligados
aos EIB, ou seja, PPE, SPEs e também outros dispositivos de I/O conectados ao processador
Cell, e os SPEs.
As mensagens enviadas por Mailboxes possuem 32 bits. Cada SPE tem duas mailboxes de
saída e uma de entrada. Devido ao pequeno tamanho das mensagens, os mailboxes são usados para
atividades de controle entre os elementos do processador Cell.
Olhando com mais detalhe cada uma das três mailboxes existentes no SPE, tem-se:
PPE mailbox queue (SPU write outbound): A SPU escreve nesta mailbox e a PPU lê
dela. Esta mailbox tem tamanho 1 e, caso a SPU tente escrever nela quando já haja
uma mensagem, o programa SPU é bloqueado. Para evitar este bloqueio, o
programa SPU deve conferir se este mailbox está vazia antes de escrever nela. Já a
PPU deve verificar se tem alguma coisa para ler nesta mailbox antes de efetuar a
leitura pois, caso não haja nada para ler, será retornado um valor qualquer na
leitura.
PPE interrupt mailbox queue (SPU write outbound): esta mailbox é semelhante à
PPE mailbox queue descrita acima, com a diferença de que, quando o SPE escreve
nela, ao invés de ser enviado uma mensagem para o PPE, é gerada uma
interrupção.
SPE mailbox queue (SPU read inbound): O PPE escreve nesta mailbox e o SPE lê
dela. Este mailbox possui 4 entradas. Quando a PPU escreve nesta mailbox ela deve
verificar antes se ela já não está cheia senão uma mensagem pode ser sobrescrita.
Já a SPU deve verificar antes de ler desta mailbox se existe alguma coisa para ler,
senão ela ficará bloqueada na leitura.
4. SIMD
Além das funcionalidades descritas acima que facilitam a implementação de códigos
combinados PPE e SPE tornando possível a orquestração destes elementos, também foram
criadas extensões para as linguagens C e C++ para facilitar a programação SIMD ou vetorial para
o processador Cell.
Por exemplo, para o PPE, foram criados tipos de dados vetoriais com 128 bits e
comandos vetoriais (intrinsics), que são comandos inline em assembly para serem usados
diretamente no código C/C++. Os instrinsics PPE são divididos em três grupos:
Specific intrinsics: são mapeados em uma única instrução assembly.
Generic intrinsics: são mapeados em uma ou mais instruções assembly.
Predicates intrinsics: comparam valores e retornam um inteiro que pode ser usado
como um valor ou como resultado de uma instrução de branch.
Os instrinsics VMX possuem o prefixo vec em frente ao mnemônico assembly que
executa a mesma operação.
Para a SPU também foram criados tipos de dados vetoriais com 128 bits e instrinsics. Os
instrisics SPE são divididos nos seguintes grupos:
Specific intrinsics: são mapeados em uma única instrução assembly.
Generic intrinsics: são mapeados em uma ou mais instruções assembly.
Composite intrinsics: formados de uma seqüência de Specific e Generic intrinsics.
Os intrinsics SPU possuem o prefixo spu em frente ao mnemônico assembly que executa
a mesma operação.
É importante frisar que os tipos de dados e intrinsics suportados por PPE e SPE, apesar de
terem muita coisa em comum, são diferentes. Em comum, por exemplo, eles têm o fato de que
todas as operações são feitas em cima de dados com 128 bits (4 full-words, 8 half-word ou 16
bytes). A SPU ainda suporta 2 double-words.
No caso da SPU, o uso de instruções SIMD é ainda mais crítico para a performance do
núcleo já que, como foi dito anteriormente, a SPU é um processador intrinsecamente vetorial.
Nele, apesar de ser possível o processamento escalar, este não aproveita toda a performance do
processador já que mesmo o processamento escalar é feito com instruções vetoriais operando
sobre vetores pois não existem instruções escalares na SPU. Além disto, as instruções escalares
são bem executadas apenas se os dados escalares estiverem alocados nos chamados preferred
slots do vetor, o que torna ainda mais penosa este tipo de operação na SPU. Caso o dado escalar
não esteja em um preferred slot, haverá uma sobrecarga para transferência deste dado para este
preferred slot, induzindo a uma performance menor no processamento da SPU. Abaixo são
mostrados os preferred slots para processamento escalar nos vetores SPU:
Figura 20 – Preferred Slots para dados escalares em registradores SPU.
Existem técnicas de programação que podem ser usadas para diminuir o impacto da perda
de performance descrita acima no processamento escalar nas SPUs. Por exemplo, pode-se tentar
promover dados escalares a vetores, seja repetindo o mesmo valor em todas as posições e
extraindo apenas um dos valores do vetor após o processamento, seja pelo agrupamento de vários
escalares em um vetor e extração apenas de um dos valores por vez ao fim de cada
processamento. Isto melhora a performance porque todo acesso a dado na SPU é feito através de
loads e stores de 128 bits por vez. Com o uso de operações escalares, cada load ou store
implicaria em uma adição de 3 outras instruções para posicionar o dado escalar no preferred slot.
Caso se use uma das estratégias acima, estas 3 instruções serão economizadas e necessitar-se-á
de apenas uma instrução adicional para extrair o resultado do vetor usado para fazer as
operações.
Além da vetorização de código que é feita pelo programador utilizando os intrinsics
descritos acima, outra alternativa é o uso de auto vetorização sobre um código escalar tradicional.
Para uso da auto vetorização, no entanto, é necessário o uso de um compilador que tenha tal
funcionalidade de análise de código, como, por exemplo, o XL C/C++, distribuído pela IBM e
que faz parte do Cell SDK 2.1. Esta funcionalidade, porém, é limitada, já que análise de códigos-
fonte para auto vetorização não são simples e nem sempre obtém resultados muito bons. Caso se
queira realmente tirar proveito do ganho de performance capaz de ser obtido através da
vetorização do código, este trabalho deverá ser feito pelo programador através do uso de
instruções SIMD.
Outra questão interessante de ser dita em relação ao uso de tipos de dados vector, que
são os tipos de dados criados para uso em instruções SIMD, é que apontadores de vector
contam suas posições em memória de 16 em 16 bytes, já que este tipo de dados possui 128 bits.
Ou seja, se declaramos vector float *p, então p + 1 apontará para uma posição de
memória 16 bytes à frente. Além disto, é possível fazer cast entre apontadores de tipos de dados
vetoriais e escalares. Por exemplo:
float *a;
vector float *b = (vector float *) a;
é uma operação possível desde que o apontador de float tenha a memória apontada por ele
alocada alinhada em 16 bytes, já que isto é requisito do tipo de dado vector. Quando uma
variável do tipo vector é declarada, a região da memória alocada para ela é pré-alinhada em 16
bytes pelo compilador.
Por último, é importante dizer que a vetorização de código não deve ser subestimada. O
poder de processamento paralelo provido por ela, já que todas as operações são feitas
simultaneamente sobre todos os dados dos vetores, sempre deve ser levado em consideração
quando se está desenhando uma solução para um problema em processadores que suportem
instruções SIMD como o Cell. Em muitos casos até, o uso de instruções vetoriais trás mais
ganhos que o uso de técnicas de paralelização explícito do processamento em múltiplos núcleos.
4. Multiplicação de matrizes
A título de exemplo de uso dos conceitos vistos acima iremos apresentar o exemplo de
multiplicação de matrizes cujo código-fonte está disponível no IBM SDK for Multicore
Acceleration 3.0. O algoritmo de multiplicação de matrizes é bem conhecido e é um exemplo
típico de algoritmo facilmente paralelizável e que consegue grandes ganhos de desempenho
através do uso de paralelismo nos seus cálculos.
O programa de demonstração de multiplicação de matrizes do IBM SDK for Multicore
Acceleration 3.0 está disponível dentro do arquivo /opt/cell/sdk/src/demos_source.tar.
Expandindo este arquivo, que é instalado juntamente com a instalação do IBM SDK for
Multicore Acceleration 3.0 através do pacote cell-demos-source, uma árvore de diretórios é
criada. O exemplo de multiplicação de matrizes fica no diretório demos/matrix_mul relativo ao
local onde o arquivo demos_source.tar foi expandido.
Entrando no diretório demos/matrix_mul podemos ver que já existe neste diretório um
exemplo completo do programa de multiplicação paralela de matrizes para ser rodado numa
plataforma Cell BE. Este programa calcula C = A * B onde A, B e C são matrizes quadradas N
x N de valores de ponto flutuante de precisão simples. O algoritmo usa particionamento em
blocos para reduzir a banda de comunicação necessária para sua execução. O tamanho do bloco é
fixado em 64. As SPEs controlam qual bloco processar através de um contador atômico unificado
controlado através das funcionalidades de comunicação atômica providas pelo MFC e que não é
foco deste mini-curso.
O projeto disponível em demos/matrix_mul é completo, ou seja, caso se deseje é
possível compilá-lo diretamente através da linha de comando usando-se os makefiles
disponibilizados e as instruções em [11] na seção “Developing Code for the Cell Broadband
Engine”. Existe ainda no arquivo README.txt deste diretório uma descrição completa da
aplicação e de todas as opções de execução disponíveis.
No entanto, conforme visto no Capítulo 2, o foco deste mini-curso é a utilização da
Interface Integrada de Desenvolvimento baseada em Eclipse para a plataforma Cell BE. Para
criarmos projetos dentro do Eclipse com os códigos-fonte fornecidos pelo exemplo de
multiplicação de matrizes do IBM SDK for Multicore Acceleration, devemos seguir os seguintes
passos:
1. Abra o Eclipse com os plug-ins do CDT e do IBM SDK for Multicore Acceleration IDE
já instalados em um novo workspace onde você irá salvar os seus projetos.
2. Mude a perspectiva padrão do Eclipse para a perspectiva C/C++. Para isso acesse a opção
Window -> Open Perspective -> Other... e escolha a perspectiva C/C++.
3. Através da opção File -> New -> Project... crie um projeto do tipo C -> Managed Make C
Project com o nome block cujo tipo de projeto seja Cell SPU Executable.
4. Crie um novo arquivo de código-fonte dentro deste projeto block recém-criado através
da opção File -> New -> Source File. Dê o nome de block.c para este arquivo.
5. Copie o conteúdo do arquivo demos/matrix_mul/spu/block.c para o arquivo block.c
criado dentro do projeto block no seu workspace Eclipse.
6. Salve o arquivo block.c. Note que o build automático do Eclipse irá ser iniciado e
alguns problemas de compilação serão encontrados no projeto pois o compilador não
achará o arquivo matrix_mul.h. Assim que importarmos o projeto PPU resolvemos este
problema.
7. Através da opção File -> New -> Project... crie um projeto do tipo C -> Managed Make C
Project com o nome matrix_mul cujo tipo de projeto seja Cell PPU Executable e que
referencie o projeto anteriormente criado block.
8. Crie um novo arquivo de cabeçalho dentro deste projeto matrix_mul recém-criado
através da opção File -> New -> Header File. Dê o nome matrix_mul.h para este
arquivo.
9. Copie o conteúdo do arquivo demos/matrix_mul/matrix_mul.h para o arquivo
matrix_mul.h criado dentro do projeto matrix_mul no seu workspace Eclipse.
10. Salve o arquivo matrix_mul.h.
11. Crie um novo arquivo de código-fonte dentro do projeto matrix_mul através da opção
File -> New -> Source File. Dê o nome matrix_mul.c para este arquivo.
12. Copie o conteúdo do arquivo demos/matrix_mul/matrix_mul.c para o arquivo
matrix_mul.c criado dentro do projeto matrix_mul no seu workspace Eclipse.
13. Salve o arquivo matrix_mul.c. O build automático do Eclipse irá ser iniciado e vários
problemas de compilação do projeto aparecerão. Para resolver estes problemas e os
problemas anteriormente encontrados no projeto block, precisamos alterar as algumas
configurações de build dos projetos.
14. Clique com o botão direito do mouse sobre o projeto block e escolha a opção Properties
do pop-up menu.
15. Na janela que aparece, escolha C/C++ Build no lado esquerdo e, no lado direito mude a
configuração para spu-gnu-release.
16. Ainda na janela de configuração das opções de build, clique no conjunto de opções
Directories embaixo de SPU GNU C Compiler with Release Options. Na opção Include
paths (-I) que aparecerá do lado direito da janela inclua o caminho para o projeto
matrix_mul no seu workspace Eclipse.
17. Clique em OK para fechar a janela.
18. Clique com o botão direito do mouse sobre o projeto matrix_mul e escolha a opção
Properties do pop-up menu.
19. Na janela que aparece, escolha C/C++ Build no lado esquerdo e, no lado direito mude a
configuração para ppu-gnu32-release.
20. Ainda na janela de configuração das opções de build, clique no conjunto de opções Inputs
embaixo de PPU GNU 32 bit Embed SPU. Na opção Embed SPU Inputs que aparecerá
do lado direito da janela inclua o caminho para o executável SPU gerado no projeto
block. Em geral este caminho pode ser representado por
"${workspace_loc:/block/spu-gnu-release/block}".
21. Ainda na janela de configuração das opções de build, clique no conjunto de opções
Libraries embaixo de PPU GNU 32 bit C Linker. Marque os checkboxes libspe2 (-lspe2),
libpthread (-lpthread) e Math library (-lm). Inclua ainda na opção Libraries (-l) a biblioteca
misc e a biblioteca numa. Na opção Library search path (-L) inclua o diretório
/opt/cell/sysroot/opt/cell/sdk/usr/lib.
22. Após estas alterações o build automático do Eclipse irá ser iniciado e os dois projetos
devem ser compilados sem erros.
23. Para lançar o projeto no ambiente simulado, basta iniciar o simulador de dentro do
Eclipse e configurar o lançamento da aplicação matrix_mul conforme descrito no
Capítulo 2, lembrando que na configuração do ambiente alvo deve ser ativada a variável
LD_LIBRARY_PATH com o valor /opt/cell/sdk/usr/lib a fim de que o sistema
operacional consiga carregar a biblioteca libmisc.so no ambiente simulado. A
configuração desta variável pode ser feita através da aba Environment da configuração de
execução de uma aplicação remota do tipo C/C++ Target Cell Application.
A parte do programa que roda na PPU basicamente é responsável por inicializar as
matrizes com dados randômicos, criar as threads SPE especificadas, enviar um mailbox para elas
indicando que elas devem iniciar seu processamento e esperar que todo o trabalho seja concluído.
Eventualmente, caso uma opção para isso seja especificada na execução do programa, a PPU irá
também verificar se a conta feita pelas SPEs está correta.
O programa SPE que roda em um ou mais núcleos é exatamente o mesmo. Inicialmente o
programa reserva as tags de DMA que ele irá usar para suas transferências de dados; inicializa os
buffers que irá utilizar para fazer double buffering a fim de aumentar o desempenho final da
aplicação, já que como vimos no Capítulo 1 a arquitetura Cell BE permite que se faça
simultaneamente nas SPEs a transferência de dados e a execução de código; pega os parâmetros
de execução através da DMA e fica esperando a chegada de uma mensagem de mailbox enviada
pelo PPE indicando que ele pode iniciar seu processamento. Assim que esta mensagem chega o
programa SPU entra em loop fazendo a transferência do bloco de dados a processar a partir da
memória principal e realizando o cálculo da multiplicação das células do bloco capturado
utilizando-se código vetorizado através de instruções SIMD nativas do SPU.
Capítulo 4: Análise de desempenho com IBM Cell BE full-system
Simulator
1. Introdução
Como já dissemos, o IBM Cell System Simulator torna possível que o desenvolvimento de
aplicações para Cell possa ser feito de forma completa mesmo que não se tenha uma máquina com
processador Cell disponível. Ele é capaz de simular a funcionalidade de todos os componentes da
arquitetura Cell BE e é capaz de simular também os SPEs e as transferências de DMA temporalmente, de
forma que é possível obter, inclusive, informações valiosas de performance da execução de uma
aplicação usando o simulador. Muitas vezes, as informações captadas pelo simulador seriam muito
difíceis de se obter mesmo usando um hardware real. Dentre as informações que o simulador gera, tem-se
dados estatísticos de ciclos executados, instruções executadas, CPI, taxas de single e dual issue,
estatísticas de stalls, uso de registradores, histograma de instruções, taxa de branch misprediction, e
outros.
As informações sobre branch misprediction, por exemplo são extremamente valiosas já que não
há suporte em hardware na SPU para branch prediction e um mispredict custa 18 ciclos de execução. O
estudo dos branch misprediction permite que diminua esta taxa. Dentre as técnicas utilizadas para
diminuição de branch misprediction, tem-se: escrever o caminho mais freqüente como código inline,
calcular os dois caminhos do branch e só depois escolher o resultado correto, loop unroll e instruções de
hint.
Além disso, o simulador possibilita o acesso aos dados de execução do processador (conteúdo da
memória, registradores PPU e SPU, LS, etc.) durante a execução dos programas.
2. SPU Dynamic Profiling com IBM Cell BE full-system Simulator
Como explicado em [12], para que a funcionalidade de profile dinâmico do simulador
seja ligada, são necessárias duas coisas. Primeiramente deve se configurar as SPEs para rodar no
modo pipeline através do botão SPU Modes da interface gráfica do simulador. Este modo liga no
simulador o componente de coleta de informações e simulação temporal de diversos
componentes da micro-arquitetura do SPU como in-order issue, ausência de register renaming,
branch hints controlados por software sem suporte algum no hardware, regras de arbitragem do
Local Store e outras. Por padrão este modo pipeline está desligado para que a simulação seja
apenas funcional e não temporal, o que a torna mais rápida.
Além disso, é necessário incluir algumas instruções especiais no código SPU sendo
executado no simulador para que o mesmo possa identificar onde ele deve ligar/desligar a coleta
de informações de performance, já que tal processo deixa a simulação bem mais lenta. Estas
instruções estão disponíveis através da interface profile.h, que fornece os procedimentos
prof_clear(), prof_start() e prof_stop(). Estes procedimentos se traduzem em instruções
assembly que não alteram o estado do sistema, como, por exemplo, and $0,$0,$0. Quando o
simulador com o modo pipeline das SPUs ligado executa uma instrução destas, ele identifica que
deve limpar, ligar ou desligar a coleta de dados de performance.
Os dados coletados durante a análise de performance podem ser visualizados de duas
formas: pela interface de linha de comando do simulador ou diretamente na interface gráfica do
simulador. Neste mini-curso, como o nosso foco é na facilidade de uso das ferramentas para a
plataforma Cell BE daremos ênfase apenas no uso da interface gráfica do simulador mostrada na
figura 21.
Figura 21: Interface gráfica do simulador
As estatísticas de execução do código SPU obtidas pela coleta de dados de performance
podem ser acessadas expandindo-se a árvore de uma SPE do lado direito da janela gráfica do
simulador e acessando o nó SPU Stats. O resultado desta ação é mostrado na figura 22.
Figura 22: Estatísticas geradas pela análise de performance do simulador.
Dentre os dados possíveis de serem analisados pelos dados estatísticos gerados pelo
simulador encontram-se: número de ciclos da SPU em que foram executados, duas instruções ou
uma instrução, número de ciclos em stall, distribuição estatística dos motivos geradores de stall,
número de instruções de branch e quantos branches foram perdidos, número de branch hints que
acertaram e muitas outras.
O simulador ainda permite, através da interface gráfica, o acesso a informações como o
histograma de instruções executadas pelo programa SPU, gráficos estatísticos sobre performance
e uso do Local Store e outros. Ele também permite que se configure um breakpoint de execução
através da análise de endereços de memória: quando um determinado endereço de memória for
lido ou escrito a execução do programa é parada e o programador pode, assim, saber exatamente
o que estava acontecendo quando tal região de memória estava sendo acessada, facilitando o
trabalho de debug de aplicações complexas com diversas threads interagindo entre si.
Gráficos estatísticos da execução no SPE podem ser acessados através do botão SPE
Visualization da interface gráfica do simulador.
Talvez a maior dificuldade que se tenha ao analisar os dados de performance gerados pelo
simulador seja achar em qual SPE simulada a thread SPE criada foi executada. Por padrão, na
arquitetura Cell BE não é possível indicar em qual núcleo SPE uma determinada thread deve ser
executada: a alocação da thread em um núcleo SPE é coordenada pelo barramento interno do
processador e nem mesmo o sistema operacional possui este controle. No caso do simulador uma
pequena regra costuma funcionar: a primeira thread SPE alocada para rodar ocupará o SPE7, a
segunda ocupará o SPE6 e assim por diante. Quando se chegar no SPE0 volta-se ao SPE7 e
assim sucessivamente. Note que esta é apenas uma dica geral e não há garantia nenhuma de que a
ordem de alocação das SPEs físicas seja esta sempre.
3. Outras ferramentas de análise de performance
Como vimos no caso do simulador, as ferramentas de análise de performance são
essenciais para se tirar um bom proveito de todo o poder de processamento que a plataforma Cell
BE pode entregar. Por isso, além do simulador, outras várias ferramentas de análise de
performance estão disponíveis para esta plataforma. Estas ferramentas muitas vezes são focadas
no SPE, já que é a partir da vetorização e paralelização de código nele é que se constrói o ganho
expressivo de performance em aplicações rodando em processadores Cell.
Destacam-se mais duas ferramentas de análise de performance além do simulador: SPU
Timing, que faz análise estática do código assembly SPU, mostrando o código e os estados de
pipeline do processador; e FDPR-Pro, que é uma ferramenta de otimização que modifica os
executáveis do programa através da análise de sua execução após o processo de link final.
3.1. SPU Timing
O SPU Timing é uma ferramenta que faz análise estática do código assembly SPU. Ele
não leva em conta instruction fetch stalls, Local Store contention e branching, assumindo
execução linear do código.
A primeira vista este tipo de análise pode parecer de pouca utilidade, mas temos que
lembrar que a SPU é um processador no qual não há chaveamento de contexto nem várias threads
concorrendo por recursos. Ou seja, um mesmo programa na SPU sempre executará exatamente
da mesma maneira, gastando o mesmo número de ciclos de clock, para a mesma entrada de dados
todas as vezes que for executado. Sob este aspecto a análise estática passa a ser valiosa para a
análise da performance obtida no processamento e para verificação dos pontos onde é possível
ainda melhorar o desempenho.
Com o SPU Timing é possível visualizar facilmente os pontos do processamento onde
estão ocorrendo stalls de pipeline ou pouco aproveitamento do dual issue das SPUs. Sabendo
onde estes problemas ocorrem, o programador pode verificar se é possível modificar alguma
coisa no código-fonte original de forma a diminuir estes efeitos indesejados.
3.2. FDPR-Pro
O Feedback Directed Program Restructuring (FDPR-Pro) é uma ferramenta de tuning de
performance que tenta reduzir o tempo de execução e o uso de memória das aplicações. Ele
trabalha com o código executável (post link) e é capaz de alterar o código executável
diretamente, sem necessidade de acesso ao código-fonte. Para isso ele é executado em duas fases:
instrumentation e optimization. Após criar a versão instrumentada do código, ele coleta
informações sobre o comportamento do programa em cima de uma carga de trabalho típica
fornecida pelo programador. Em seguida, ele cria uma nova versão do programa otimizada para a
carga de trabalho típica que, em geral, é mais rápida e usa menos memória que a versão original.
Capítulo 5 Trabalhos Relacionados
1.Introdução
Este capítulo final do nosso minicurso tem por objetivo de relacionar as linguagens de
programação que estão em desenvolvimento para plataforma Cell BE, os trabalhos de pesquisas
em Universidades e ferramentas comerciais para prototipagem rápida no Cell.
Podemos relacionar as seguintes ferramentas de software e tecnologias:
1. IBM Octopiler [19].
2. Código e Particionamento de dados para memória local do processador Cell BE [20]
3. Compilador CellSs para OpenMP em memória privada [21, 22, 23].
4. Glimpses e Cellule.
Na tabela 1 a seguir, relacionamos os trabalhos mais importantes desenvolvidos na
plataforma Cell BE:
Computação Científica Softwares Comerciais
Desenvolvimento de Algoritmos Numéricos
Paralelos de Alta Performance para o
Processador Cell [24]
Computação Científica para Cluster de
Playstation 3 [25].
Plataforma de Desenvolvimento RapidMind e
Programação Paralela de Dados [26]
Biblioteca de Processamento de Sinais pelo
MIT
Multicore Framework (MFC) para Cell BE
pela Mercury Systems [27]
Mercado Financeiro [29]
Aplicações Aeroespaciais e Geociências
Tabela 1: Comparação entre Softwares de Computação Científica e Comerciais
Atualmente, várias linguagens de programação são portadas para novo paradigma de
programação multicore do Cell BE. Descrevemos algumas delas na tabela 2:
Linguagens de Programação Universidade / Empresa
Charm++ [28] University of Illinois – Urbana Champgne (UIUC)
Programação Sintética com Phyton University of Indiana
Programação OpenMP University Polithecnical of Barcelona (UPC)
Programação para Playstation – Desenvolvimento para
Jogos
Programação Sequoia no PS3 [29] Stanford University
Tabela 02: Linguagens de Programação no Cell
O Grupo de Computação Pervasiva e Processamento de Alto Desempenho (PAD), em
especial, o aluno de doutorado Roberto Kenji Hiramtsu, da Universidade de São Paulo
desenvolveu um software para detecção de faces, chamado CELL FaceDetect [30], que utiliza a
biblioteca OpenCV, otimizado para Cell BE. Este software ganhou em quarto lugar na região
das Américas, o concurso da IBM - “Cell Contest'07 Beyond on Gaming” [31]. Para o trabalho
de Tese, está sendo propostos vários módulos de reconhecimento de faces para um sistema de
vídeo segurança.
Referências
[1] J. M. Eastep. Msc Thesis, Massachusetts Institute of Technology, March 2007.
[2] M. Gschwind, H. P. Hosftee et al, Y. Watanabe and T. Yamazaki. Paper in Hot Chips 17.
In (Synergistic Processing in Cell's Multicore Architecture), Stanford University, pages 10-
24, 2006.
[3] H. P. Hosftee. Paper IEEE in HPCA-11, “Power Efficient Processor Architecture and The
Cell Processor”, pp. 258-262, February 2005.
[4] J. Easton, I. Meents, O. Stephan, H. Zisgen, S. Kato. IBM Whitepaper, “Porting Financial
Markets Applications to the Cell Broadband Engine Architecture”, June 2007.
[5] F. Pham et al. Paper in ISSCC Dig. Tech, “The Design and Implementation of a First-
Generation CELL Processor,” Paper 10.2, pp. 184-185, Feb., 2005.
[6] B. Flachs et al. Paper in ISSCC Dig. Tech, “A Streaming Processing Unit for a CELL
Processor”, Paper 7.4, pp. 134-135, Feb., 2005.
[7] Duc Vianney. “Cell Software Solutions Models Programming”, Game Developers
Conference 2006. Presentation. Available on:
www.power.org/resources/devcorner/cellcorner/DucVianney_GDC-
CellSoftwareSolutionsProgrammingModel.pdf
[8] H. P. Hosftee. White Paper, “Introduction to the Cell Broadband Engine”, IBM
Corporation, 31/10/2005.
[9] J. A. Kahle, M. N. Day, H. P. Hosftee, et al. IBM Journal of Research and Development,
“Introduction to the Cell Multiprocessor”, volume 49, Number 4/5, 2005.
[10] Barcelona Supercomputing Center Site. Disponível em:
http://www.bsc.es/plantillaG.php?cat_id=179
[11] Software Development Kit for Multicore Acceleration Version 3.0 Programming Tutorial
Draft disponível em /opt/cell/sdk/docs/programming através da instalação do pacote
cell-documentation.
[12] Lewin Edwards. An introduction to compiling for the Cell Broadband Engine architecture,
Part 1: “A birds-eye View”. Disponível em: http://www.ibm.com/developerworks/edu/pa-dw-pa-
cbecompile1-i.html?S_TACT=105AGX16&S_CMP=LP
[13] Alexandre E. Eichenberger, Kathryn O'Brien, Kevin K. O'Brien, Peng Wu, Tong Chen,
Peter H. Oden, Daniel A. Prener, Janice C. Shepherd, Byoungro So, Zehra Sura, Amy
Wang, Tao Zhang, Peng Zhao, and Michael Gschwind. “Optimizing Compiler for the
CELL Processor”, PACT05, Saint Louis, Missouri. Disponível em: http://pact05.ce.ucsc.edu/
[14] Compiler Technology for Scalable Architectures. Disponível em:
http://domino.research.ibm.com/comm/research_projects.nsf/pages/cellcompiler.index.html
[15] Software Development Kit for Multicore Acceleration Version 3, “Installation Guide
Version 3.0”, Setembro, 2007. Disponivel no AlphaWorks:
[16] Portal CellBR Website. Disponivel em: http://www.pad.lsi.usp.br/cell. Acessado em: 25 de setembro
de 2007.
[17] Eclipse.org. Disponível em: http://www.eclipse.org. Acessado em: 25 de setembro de 2007.[18] IBM
Book. “SPE Runtime Management Library Version 2.2”. Disponível em: http://www-
01.ibm.com/chips/techlib/techlib.nsf/techdocs/4818FA471C13A1BC872572AB006C4139. Acessado em: 25
de setembro de 2007.
[19] IBM Octopiler Site. Disponível em:
http://domino.research.ibm.com/comm/research_projects.nsf/pages/cellcompiler.index.html. Acesso em 25
de setembro de 2007.
[20] Obrien. Apresentação no Sony/Toshiba/IBM Workshop on Software and Applications for
Cell/BE processor. Georgia Tech, June 18-19, 2007. Disponível em:
http://sti.cc.gatech.edu/program.html. Acessado em: 25 de setembro de 2007.
[21] J.M. Perez, P. Bellens, R.M. Badia, and J. Labarta. Artigo publicado no IBM Journal of
Research and Development. “CellSs: Making it easier to program the Cell Broadband
Engine processor”, Cell Broadband Engine Technology and Systems, Volume 51, Number
5, 2007.
[22] P. Bellens, J. Perez, R. Badia, J. Labarta. Artigo publicado no SC'07. “CellSs: a
programming model for the cell BE architecture”, Proceedings of the 2006 ACM/IEEE
Conference on Supercomputing, number 86, 2006.
[23] Cell Superscalar Site. Barcelona Supercomputing Center. Disponível em:
http://www.bsc.es/plantillaG.php?cat_id=179. Acessado em: 25 de setembro de 2007.
[24] A. Buttari, J. Dongarra, and J. Kurzak. Relatório Técnico. “Limitations of the PlayStation 3
for High Performance Cluster Computing”, UT-CS-07-597, May 2007.
[25] Buttari, A., Luszczek, P., Kurzak, J., Dongarra, J., Bosilca, G. Relatório Técnico. “SCOP3:
A Rough Guide to Scientific Computing On the PlayStation 3”, University of Tennessee
Computer Science Dept. Technical Report, UT-CS-07-595, April 17, 2007.
[26] RapidMind Website. Disponível em: http://www.rapidmind.net/case-studies.php. Acessado em: 25
de setembro de 2007.
[27] Mercury System Website. Disponível em: http://www.mc.com/microsites/cell/. Acessado em: 25
de setembro de 2007.
[28] D. Kunzman, G. Zheng, E. Bohm, L. V. Kale. Poster. “Charm++ Simplifies Programming
for the Cell Processor”. Disponível em: http://charm.cs.uiuc.edu/posters/. Acessado em: 25 de
setembro de 2007.
[29] Houston M. Apresentação no CscADS Workshop. “Sequoia”. Stanford University, July 9th
,
2007. Disponível em: http://cscads.rice.edu/workshops/july2007/autotune-slides-
07/Houston.pdf
[30] Projeto CELL FaceDetect Website. Disponível em:
http://www.pad.lsi.usp.br/cell/index.php?option=com_content&task=view&id=21&Itemid=0. Acessado
em: 25 de setembro de 2007.
[31] Concurso Cell Contest'07 Website. Disponível em: http://www-
304.ibm.com/jct09002c/university/students/contests/cell/index.html

Mais conteúdo relacionado

Destaque

Подводим итоги. Открываем перспективы. - Фомина О.В.
Подводим итоги. Открываем перспективы. - Фомина О.В.Подводим итоги. Открываем перспективы. - Фомина О.В.
Подводим итоги. Открываем перспективы. - Фомина О.В.CollegeTsaritsyno
 
Aspectos éticos y Sociales en los sistemas de información
Aspectos éticos y Sociales en los  sistemas de informaciónAspectos éticos y Sociales en los  sistemas de información
Aspectos éticos y Sociales en los sistemas de informaciónUTH
 
Gestão de Projetos e Empreendedorismo (21/05/2013)
Gestão de Projetos e Empreendedorismo (21/05/2013)Gestão de Projetos e Empreendedorismo (21/05/2013)
Gestão de Projetos e Empreendedorismo (21/05/2013)Alessandro Almeida
 
Btth 7 mau_hoi_tren nhieu bang
Btth 7 mau_hoi_tren nhieu bangBtth 7 mau_hoi_tren nhieu bang
Btth 7 mau_hoi_tren nhieu bangCon Người
 
Gestão de Projetos e Empreendedorismo (22/05/2013)
Gestão de Projetos e Empreendedorismo (22/05/2013)Gestão de Projetos e Empreendedorismo (22/05/2013)
Gestão de Projetos e Empreendedorismo (22/05/2013)Alessandro Almeida
 
Palestra Big Festival 03072015 Monetização
Palestra Big Festival 03072015 MonetizaçãoPalestra Big Festival 03072015 Monetização
Palestra Big Festival 03072015 MonetizaçãoGamebiz
 
Entrepreneurship as a means to create islamic economy
Entrepreneurship as a means to create islamic economyEntrepreneurship as a means to create islamic economy
Entrepreneurship as a means to create islamic economyMurray Hunter
 
Intranet Innovation Awards 2014 Gold Winner Accolade / Embrace SBS / Umbrella
Intranet Innovation Awards 2014 Gold Winner Accolade / Embrace SBS / UmbrellaIntranet Innovation Awards 2014 Gold Winner Accolade / Embrace SBS / Umbrella
Intranet Innovation Awards 2014 Gold Winner Accolade / Embrace SBS / UmbrellaMalengo
 

Destaque (15)

Подводим итоги. Открываем перспективы. - Фомина О.В.
Подводим итоги. Открываем перспективы. - Фомина О.В.Подводим итоги. Открываем перспективы. - Фомина О.В.
Подводим итоги. Открываем перспективы. - Фомина О.В.
 
1word
1word1word
1word
 
Aspectos éticos y Sociales en los sistemas de información
Aspectos éticos y Sociales en los  sistemas de informaciónAspectos éticos y Sociales en los  sistemas de información
Aspectos éticos y Sociales en los sistemas de información
 
Resume - RDL 150703
Resume - RDL 150703Resume - RDL 150703
Resume - RDL 150703
 
Gestão de Projetos e Empreendedorismo (21/05/2013)
Gestão de Projetos e Empreendedorismo (21/05/2013)Gestão de Projetos e Empreendedorismo (21/05/2013)
Gestão de Projetos e Empreendedorismo (21/05/2013)
 
iphone 5 review
iphone 5 reviewiphone 5 review
iphone 5 review
 
Btth 7 mau_hoi_tren nhieu bang
Btth 7 mau_hoi_tren nhieu bangBtth 7 mau_hoi_tren nhieu bang
Btth 7 mau_hoi_tren nhieu bang
 
Paradigmas de la investigacion social1
Paradigmas de la investigacion social1Paradigmas de la investigacion social1
Paradigmas de la investigacion social1
 
Qué es una página web
Qué es una página webQué es una página web
Qué es una página web
 
Gestão de Projetos e Empreendedorismo (22/05/2013)
Gestão de Projetos e Empreendedorismo (22/05/2013)Gestão de Projetos e Empreendedorismo (22/05/2013)
Gestão de Projetos e Empreendedorismo (22/05/2013)
 
Eav ensayo (1)
Eav  ensayo (1)Eav  ensayo (1)
Eav ensayo (1)
 
Palestra Big Festival 03072015 Monetização
Palestra Big Festival 03072015 MonetizaçãoPalestra Big Festival 03072015 Monetização
Palestra Big Festival 03072015 Monetização
 
Entrepreneurship as a means to create islamic economy
Entrepreneurship as a means to create islamic economyEntrepreneurship as a means to create islamic economy
Entrepreneurship as a means to create islamic economy
 
Law firm interview tips
Law firm interview tipsLaw firm interview tips
Law firm interview tips
 
Intranet Innovation Awards 2014 Gold Winner Accolade / Embrace SBS / Umbrella
Intranet Innovation Awards 2014 Gold Winner Accolade / Embrace SBS / UmbrellaIntranet Innovation Awards 2014 Gold Winner Accolade / Embrace SBS / Umbrella
Intranet Innovation Awards 2014 Gold Winner Accolade / Embrace SBS / Umbrella
 

Semelhante a 33149_1

Computação de Alto Desempenho com PS3
Computação de Alto Desempenho com PS3Computação de Alto Desempenho com PS3
Computação de Alto Desempenho com PS3Orlando Junior
 
Processadores de servidores apresentação
Processadores de servidores apresentaçãoProcessadores de servidores apresentação
Processadores de servidores apresentaçãoMiguel Ferreira
 
Processadores de servidores apresentação
Processadores de servidores apresentaçãoProcessadores de servidores apresentação
Processadores de servidores apresentaçãoMiguel Ferreira
 
Palestra PET.Com - Sistemas Embarcados
Palestra PET.Com - Sistemas EmbarcadosPalestra PET.Com - Sistemas Embarcados
Palestra PET.Com - Sistemas EmbarcadosPET Computação
 
Arquitetura de computadores Módulo 4
Arquitetura de computadores Módulo 4Arquitetura de computadores Módulo 4
Arquitetura de computadores Módulo 4Luis Ferreira
 
Evolução da Informática - Resumo
Evolução da Informática - ResumoEvolução da Informática - Resumo
Evolução da Informática - Resumoprapina
 
Gerenciador do atmega16
Gerenciador do atmega16Gerenciador do atmega16
Gerenciador do atmega16Gabriel Lima
 
Aquitetura dos Processadores Multicore
Aquitetura dos Processadores MulticoreAquitetura dos Processadores Multicore
Aquitetura dos Processadores MulticoreIsraelCunha
 
ESTUDO DE PERFORMANCE DAS ARQUITETURAS RISC E CISC. UM BREVE HISTÓRICO DA EVO...
ESTUDO DE PERFORMANCE DAS ARQUITETURAS RISC E CISC. UM BREVE HISTÓRICO DA EVO...ESTUDO DE PERFORMANCE DAS ARQUITETURAS RISC E CISC. UM BREVE HISTÓRICO DA EVO...
ESTUDO DE PERFORMANCE DAS ARQUITETURAS RISC E CISC. UM BREVE HISTÓRICO DA EVO...Daniel Caixeta
 
Estudo de performance_das_arquiteturas_risc_e_cisc._um_breve_historico_da_arq...
Estudo de performance_das_arquiteturas_risc_e_cisc._um_breve_historico_da_arq...Estudo de performance_das_arquiteturas_risc_e_cisc._um_breve_historico_da_arq...
Estudo de performance_das_arquiteturas_risc_e_cisc._um_breve_historico_da_arq...César Júlio
 
Multithreaded tecnologia
Multithreaded tecnologia Multithreaded tecnologia
Multithreaded tecnologia J Chaves Silva
 
Webinar: Oportunidades e requisitos no projeto de hardware para IoT
Webinar: Oportunidades e requisitos no projeto de hardware para IoTWebinar: Oportunidades e requisitos no projeto de hardware para IoT
Webinar: Oportunidades e requisitos no projeto de hardware para IoTEmbarcados
 
Android Core Aula 1 - Histórico, Arquitetura e Compilação da plataforma
Android Core Aula 1 - Histórico, Arquitetura e Compilação da plataformaAndroid Core Aula 1 - Histórico, Arquitetura e Compilação da plataforma
Android Core Aula 1 - Histórico, Arquitetura e Compilação da plataformaFelipe Silveira
 
Apostila ibge informatica
Apostila ibge informaticaApostila ibge informatica
Apostila ibge informaticaCONCURSEIRA1985
 
Artigo tecpar ráfagan - Pesquisando a viabilidade de utilização de engin...
Artigo tecpar   ráfagan - Pesquisando a viabilidade de utilização de engin...Artigo tecpar   ráfagan - Pesquisando a viabilidade de utilização de engin...
Artigo tecpar ráfagan - Pesquisando a viabilidade de utilização de engin...Ráfagan Abreu
 
Programe a STM32L4 Discovery kit IoT node com ARM mbed
Programe a STM32L4 Discovery kit IoT node com ARM mbedPrograme a STM32L4 Discovery kit IoT node com ARM mbed
Programe a STM32L4 Discovery kit IoT node com ARM mbedFabio Souza
 

Semelhante a 33149_1 (20)

Computação de Alto Desempenho com PS3
Computação de Alto Desempenho com PS3Computação de Alto Desempenho com PS3
Computação de Alto Desempenho com PS3
 
Artigo tv digital
Artigo tv digitalArtigo tv digital
Artigo tv digital
 
Processadores de servidores apresentação
Processadores de servidores apresentaçãoProcessadores de servidores apresentação
Processadores de servidores apresentação
 
Processadores de servidores apresentação
Processadores de servidores apresentaçãoProcessadores de servidores apresentação
Processadores de servidores apresentação
 
Palestra PET.Com - Sistemas Embarcados
Palestra PET.Com - Sistemas EmbarcadosPalestra PET.Com - Sistemas Embarcados
Palestra PET.Com - Sistemas Embarcados
 
SDAC 12º - M9 TGEI
SDAC 12º - M9 TGEISDAC 12º - M9 TGEI
SDAC 12º - M9 TGEI
 
Arquitetura de computadores Módulo 4
Arquitetura de computadores Módulo 4Arquitetura de computadores Módulo 4
Arquitetura de computadores Módulo 4
 
Evolução da Informática - Resumo
Evolução da Informática - ResumoEvolução da Informática - Resumo
Evolução da Informática - Resumo
 
Gerenciador do atmega16
Gerenciador do atmega16Gerenciador do atmega16
Gerenciador do atmega16
 
Aquitetura dos Processadores Multicore
Aquitetura dos Processadores MulticoreAquitetura dos Processadores Multicore
Aquitetura dos Processadores Multicore
 
ESTUDO DE PERFORMANCE DAS ARQUITETURAS RISC E CISC. UM BREVE HISTÓRICO DA EVO...
ESTUDO DE PERFORMANCE DAS ARQUITETURAS RISC E CISC. UM BREVE HISTÓRICO DA EVO...ESTUDO DE PERFORMANCE DAS ARQUITETURAS RISC E CISC. UM BREVE HISTÓRICO DA EVO...
ESTUDO DE PERFORMANCE DAS ARQUITETURAS RISC E CISC. UM BREVE HISTÓRICO DA EVO...
 
Estudo de performance_das_arquiteturas_risc_e_cisc._um_breve_historico_da_arq...
Estudo de performance_das_arquiteturas_risc_e_cisc._um_breve_historico_da_arq...Estudo de performance_das_arquiteturas_risc_e_cisc._um_breve_historico_da_arq...
Estudo de performance_das_arquiteturas_risc_e_cisc._um_breve_historico_da_arq...
 
Multithreaded tecnologia
Multithreaded tecnologia Multithreaded tecnologia
Multithreaded tecnologia
 
Webinar: Oportunidades e requisitos no projeto de hardware para IoT
Webinar: Oportunidades e requisitos no projeto de hardware para IoTWebinar: Oportunidades e requisitos no projeto de hardware para IoT
Webinar: Oportunidades e requisitos no projeto de hardware para IoT
 
Android Core Aula 1 - Histórico, Arquitetura e Compilação da plataforma
Android Core Aula 1 - Histórico, Arquitetura e Compilação da plataformaAndroid Core Aula 1 - Histórico, Arquitetura e Compilação da plataforma
Android Core Aula 1 - Histórico, Arquitetura e Compilação da plataforma
 
Apostila ibge informatica
Apostila ibge informaticaApostila ibge informatica
Apostila ibge informatica
 
Artigo tecpar ráfagan - Pesquisando a viabilidade de utilização de engin...
Artigo tecpar   ráfagan - Pesquisando a viabilidade de utilização de engin...Artigo tecpar   ráfagan - Pesquisando a viabilidade de utilização de engin...
Artigo tecpar ráfagan - Pesquisando a viabilidade de utilização de engin...
 
Informatica bb 2011
Informatica bb 2011Informatica bb 2011
Informatica bb 2011
 
Aula 4
Aula 4Aula 4
Aula 4
 
Programe a STM32L4 Discovery kit IoT node com ARM mbed
Programe a STM32L4 Discovery kit IoT node com ARM mbedPrograme a STM32L4 Discovery kit IoT node com ARM mbed
Programe a STM32L4 Discovery kit IoT node com ARM mbed
 

33149_1

  • 1. Programando Multicore com IBM-full System Simulator – Cell Broadband Engine Jussara M. Kofuji, Sergio T. Kofuji, Roberto K. Hiramatsu PAD-LSI/USP – Universidade de São Paulo Av. Prof. Luciano Gualberto trav3 Cidade Universitária, 158 – São Paulo - CEP: 05508-970 {jussara, kofuji, kenji}@pad.lsi.usp.br Leonardo A. G. Garcia IBM Brasil – Centro de Tecnologia Linux – LTC Rod. Jornalista Francisco Aguirre Proença, km 09 – Hortolândia, SP – CEP: 13186-900 lagarcia@br.ibm.com Resumo Este minicurso pretende apresentar novos conceitos de programação de uma arquitetura heterogênea chamada “Cell Broadband Engine”, desenvolvida por um consórcio formado por Sony, Toshiba e IBM. Atualmente esta arquitetura está presente no PlayStation 3, na IBM Blade Cell QS21 e tem proposta para ser implementada na TV Digital, sendo utilizada para resolver problemas que demandam uma computação de alto desempenho e alta resolução de imagem. As arquiteturas multicore, em geral, estão impulsionando o desenvolvimento de aplicações de alto desempenho que utilizam técnicas de programação que exploram o paralelismo de hardware e software. O minicurso visa introduzir o uso do Simulador para plataforma Cell, apresentando o ambiente de desenvolvimento provido pelo recente lançamento do Cell SDK 3.0 e o IDE baseado em Eclipse para o Cell SDK. Faremos uma introdução sobre o uso do IDE: criação de projetos, compilação e debug de aplicações com o Cell System Simulator e otimização de código usando-se os mecanismos de comunicação entre processadores providos pela arquitetura Cell Broadband Engine.
  • 2. Capítulo 1: Introdução à Arquitetura Cell BE 1. Introdução Nosso mini-curso é baseado essencialmente na Arquitetura “Cell Broadband Engine” (Cell BE), considerada uma arquitetura heterogênea. Atualmente, podemos destacar dois tipos de arquiteturas multicore: arquitetura multicore homogênea (como por exemplo, Intel Core 2 Duo ou Quadcore, UltraSPARC T1/T2) e arquiteturas multicore heterogênea (Processador Cell BE, Processadores Intel com GPU/FPGA). Conceitualmente, a arquitetura multicore homogênea, segundo Jonathan [1] em sua tese intitulada “Evolve: A Preliminary Multicore Architecture for Introspective Computing”, é uma arquitetura com blocos homogêneos enfileirados, ou seja, cada núcleo é idêntico ao outro. Em contrapartida, numa arquitetura heterogênea os blocos formadores podem ser diferentes e ter, inclusive, funções especializadas. Na figura 1 e 2, apresentamos respectivamente, exemplo de arquitetura homogênea e arquitetura heterogênea. Figura 01: Arquitetura Multicore Homogêneo [1] Figura 02: Sistema Cell Broadband Engine [2] Como citado anteriormente, a partir da Aliança IBM, SCEI/Sony e Toshiba formada em 2000, começou a trajetória do desenvolvimento do processador Cell. Em 2001, iniciou-se o desenvolvimento da arquitetura Cell BE no Centro de Pesquisa da IBM em Austin, Texas. Tanto o hardware quanto o software foram e estão sendo desenvolvidos simultaneamente. Em 2003, a Toshiba projetou a memória XDR DRAM que hoje equipa algumas das máquinas com
  • 3. processadores Cell BE. Esta memória é capaz de operar em velocidades de barramento mais altas, quando comparadas às memórias convencionais. Esta característica é essencial para se ter um bom aproveitamento do poder de processamento provido pelo processador Cell BE, pois ele possui um desenho inovador no seu barramento de comunicação interno que possibilita uma grande taxa de transferência interna entre núcleos e entre os núcleos e a memória externa. Em 2004, a arquitetura Cell BE é apresentada à comunidade acadêmica na conferência internacional de circuitos de estados sólidos (ISSCC’2005). Em 2005, foi anunciado o lançamento do PlayStation 3 pela Sony. E, finalmente, em 2006, a IBM ganha a licitação do Laboratório de Los Alamos para desenvolver o supercomputador RoadRunner baseado no processador Cell BE. A versão inicial do processador Cell BE foi implementada em sistemas de console de jogos (PlayStation 3 – PS3) pela Sony, posteriormente em servidores com dois processadores Cell, linha de servidores chamada IBM Blade Cell (atualmente, modelo QS20) e a proposta de implementação do processador na tecnologia HDTV pela Toshiba, em especial, em servidores “home media”. está sendo usada em alguns produtos que exigem grande poder computacional: sistemas de console de jogos (PlayStation3), Blades (IBM Blade Cell), HDTV, servidores de “home media” e supercomputadores. Apesar destas plataformas comerciais equipadas com processador Cell BE, existe um plano em aberto pelo consórcio para continuar a evolução da arquitetura como veremos adiante neste mini-curso. Em termos de software, as três empresas do consórcio, além de empresas parceiras, também tiveram participação no desenvolvimento de suas plataformas de desenvolvimento de aplicações para o processador Cell BE. Especificamente neste mini-curso iremos comentar sobre o Cell BE SDK da IBM, que é a única plataforma de desenvolvimento para processadores Cell BE fornecida gratuitamente. O IBM Cell BE SDK passou pelas seguintes fases: versão alpha (SDK 1.1), versão beta (SDK 2.0 e SDK 2.1) e versão “produto” (SDK 3.0). Já em termos de hardware, tivemos uma evolução de escalabilidade do PCI express e memória (1 GB, 2 GB). O processador Cell BE foi desenvolvido especialmente para jogos, aplicações multimídia e outros tipos de aplicações que necessitem de alto poder de computação numérica. Já existem diversos trabalhos relacionados com processamento de imagens (como ressonância magnética), análise de imagens, criação de conteúdo digital (jogos e filmes), distribuição de conteúdo, próxima geração da física baseada em visualização, vídeo conferência, aplicações de streaming (codecs), simulações físicas e ciência [3]. Recentemente, a IBM divulgou um caso de estudo baseado em aplicações para o mercado financeiro [4]. Este primeiro capítulo de introdução à arquitetura Cell BE está organizado nos seguintes tópicos: Arquitetura Cell BE e seus Elementos, Cell BE Roadmap, Cell SDK 3.0.
  • 4. 1.1 Público Alvo Este mini-curso foi planejado com intuito de oferecer uma visão mais aprofundada da Arquitetura Multicore Heterogênea – o Processador Cell Broadband Engine, apresentar as potencialidades desta arquitetura para aplicações que demandam um alto poder de computação (em especial, área de processamento de imagens, visualização e computação gráfica, modelos matemáticos, algoritmos numéricos paralelos, geociência, aeroespacial, biomédica, arquitetura de computadores, programação paralela). Outros objetivos específicos são: introduzir conceitos básicos de programação na plataforma Cell BE, apresentar modelos de programação e o uso do simulador da IBM, bem como as ferramentas externas de otimização de códigos e análise de performance. Nosso mini-curso começou a partir das atividades de pesquisa desenvolvidas na disciplina de Arquiteturas Avançadas de Computadores da Escola Politécnica da Universidade de São Paulo (EPUSP), de visitas técnicas do Engenheiro Chefe do desenvolvimento do processador Cell BE – Peter Hosftee, da participação em um projeto do Cell BE no Programa IBM Extreme Blue e parceria técnica para desenvolver o Centro de Competência Cell no Brasil. A princípio, o mini-curso destina-se a todos interessados em aprender os novos paradigmas de programação multicore heterogêneo, alunos e pesquisadores da área de Arquitetura de Computadores que se interessam por processadores modernos, simuladores, compiladores, programação paralela; pesquisadores e profissionais que desejam desenvolver aplicações científicas na plataforma Cell BE; engenheiros e pesquisadores interessados em programação para processamento de áudio e vídeo; alunos, físicos e pesquisadores interessados em simulação de Fluídos Dinâmicos; e finalmente médicos e pesquisadores interessados em Ressonância Magnética. 2. Arquitetura Cell BE e seus Elementos Até pouco tempo atrás, quando se falava em processador, pensava-se logo em uma unidade indivisível em sua visão macro, composta de várias unidades funcionais trabalhando em conjunto para um objetivo único comum, que era executar uma thread de código por vez. Nesta concepção, cada processador era formado por um único núcleo de processamento, formado pelas suas unidades funcionais. Nos últimos tempos, porém, vêm ganhando visibilidade no mercado de hardware as arquiteturas de processadores multicore. Estas arquiteturas nada mais são que uma evolução em relação à arquitetura de um núcleo por processador, possibilitando que se tenham dois ou mais núcleos dentro de um mesmo processador. Este aumento no número de núcleos foi possível devido à tecnologia de fabricação de circuitos que evoluiu, possibilitando a miniaturização do transistor. Deste modo, a fabricação de processadores com mais de um núcleo de processamento se tornou uma solução comercial. Contudo, com as mesmas características das unidades funcionais dos núcleos de processamento: capacidade de processamento de uma thread de código por vez, no caso das SPE’s no processador Cell.
  • 5. Em referência às arquiteturas multicore homogêneas muitas empresas como Intel, AMD e SUN fabricaram seus processadores seguindo o conceito de multiplicação dos núcleos de processamento iguais em um único processador. O processador Cell BE foi a primeira arquitetura multicore heterogênea, onde os núcleos de processamento são diferentes quanto à organização do processador. O processador Cell BE é um microprocessador multicore heterogêneo com 1 elemento de processamento principal (PPE – Power Processor Element) e 8 elementos de processamento sinergísticos (SPE's- Sinergistic Processor Element) [5]. O PPE é um processador de propósito geral e os SPEs são processadores dedicados, cada um formado por uma unidade de processamento sinergístico (SPU) com 256 Kbytes de armazenamento local e um controlador de fluxo de memória (MFC) [6]. Na figura3, apresentamos a arquitetura do sistema Cell BE. A arquitetura Cell Broadband Engine é formada por um elemento de processamento principal (PPE) e 8 elementos de processamento sinergísticos (SPE's) que trabalham de forma unificada. O elemento de barramento de interconexão conecta os elementos de processamento com um subsistema de comunicação de alta velocidade. Figura 3: Arquitetura do Sistema Cell [2] O Cell BE pode rodar até 10 threads simultaneamente, com até 200 GFlops de operações sobre ponto flutuante de precisão simples, até 300 GB/s de velocidade de transferência interna e até 25 GB/s de velocidade de acesso à memória.
  • 6. O caminho para atingir esta alta capacidade de processamento atravessou várias barreiras. A forma inovadora de ultrapassar estas barreiras levou a arquitetura Cell BE a um desenho inusitado até então: a presença de núcleos diferentes dentro do mesmo processador trabalhando de forma combinada. As principais barreiras existentes hoje na evolução das arquiteturas de computadores são: barreira de potência, barreira de memória e barreira de freqüência. A barreira de potência reflete o fato de a dissipação de calor das tecnologias de transistor atuais ter chegado a níveis críticos que atrapalham não só o bom funcionamento dos processadores mas também o uso eficiente da energia elétrica. O processador Cell BE contorna a barreira de potência por ser uma arquitetura heterogênea. Um processador heterogêneo chaveia menos de contexto e, por isso, gasta mais tempo processando a aplicação fim e não o código de controle do sistema operacional, aumentando a eficiência de entrega de instrução por consumo de energia. Além disso, o multicore permite que se tenham núcleos mais simples que entregam uma capacidade conjunta maior e, com núcleos mais simples, é possível a operação em alta freqüência com menores voltagens, diminuindo também o problema de consumo de energia. A barreira de memória reflete o fato de a freqüência de trabalho do processador ter aumentado de forma muito mais rápida que a freqüência de trabalho das memórias DRAM. Com isso, existem verdadeiros gargalos de processamento em programas que acessam muito a memória. Os vários níveis de cache presentes nas arquiteturas atuais tentam amenizar este problema, mas a barreira de memória é, ainda assim, um problema que impacta bastantes programas que demandam alto poder de processamento. Em alguns casos até, os caches chegam a atrapalhar: isso é relativamente comum em programas que demandam muitos cálculos e poucos acessos à memória ou acessos a regiões esparsas da memória. Para atacar este problema, a arquitetura Cell BE suporta carregamentos assíncronos entre os núcleos, através de streaming DMA. Além disto, a memória é separada em três níveis: memória principal, Local Storage e Register File. A barreira de freqüência reflete o fato de o simples aumento da freqüência de trabalho dos processadores nas arquiteturas atuais causarem problemas físicos devido a interferências e dissipação de calor que impedem maiores ganhos de velocidade com o aumento de pipelines, por exemplo. A barreira de freqüência nitidamente impediu que nos últimos três anos o aumento de freqüência dos processadores seguisse a Lei de Moore, que ditou este aumento desde meados da década de 1980. Para atacar este problema, a arquitetura Cell BE com seus núcleos heterogêneos possibilitou se tiver núcleos com funções mais especializadas e, portanto, com desenho mais simples, permitindo-os operar em freqüências mais altas. A seguir, vamos descrever os componentes mais importantes da arquitetura Cell Broadband Engine. 2.1 PPE O PPE é formado por um processador de propósito genérico PowerPC RISC de 64 bits capaz de executar até duas threads simultaneamente com cache L1 de 32 KB para dados e 32 KB para
  • 7. instruções e cache L2 de 512 KB para dados e instruções rodando a 3,2 GHz. Além disso, existe suporte para instruções vetoriais VMX no PPE capaz de executar operações sobre inteiros e pontos flutuantes de precisão simples. O conjunto com o processador PowerPC e as caches L1 é conhecido como Power Processor Unit (PPU). Como a PPU é um processador totalmente compatível com PowerPC, é possível rodar programas compilados para este plataforma em Cell sem nenhum problema. O sistema operacional também roda no núcleo PPU e possui extensões para conseguir administrar e trabalhar de forma cooperativa com os núcleos SPEs. Porém, é importante frisar que o sistema operacional não roda nos núcleos SPEs. A PPU, no entanto, tem uma desvantagem em relação a outros PowerPC. Como ela está embarcada dentro de um processador multicore mais complexo, seu projeto é mais simples que o de outros PowerPC atual e, por isso, a eficiência de uma aplicação PowerPC rodando em um Cell é consideravelmente menor que a eficiência desta mesma aplicação rodando em um processador PowerPC de última geração. 2.2 SPE Cada SPE possui uma Synergestic Processor Unit (SPU) e um Memory Flow Controller (MFC), responsável pela movimentação e sincronização de dados e interface com o Element Interconnect Bus (EIB). A SPU é um processador in-order com unidades funcionais SIMD de 128 bits capaz de processar inteiros e pontos flutuantes de precisão simples e dupla. Cada SPU tem uma memória local para dados e instruções, o Local Store (LS), de 256 KB e um Register File com 128 registradores de 128 bits. A SPU tem 9 unidades funcionais distribuídas em 2 pipelines: para se enviar 2 instruções para execução por ciclo é preciso que as instruções estejam alinhadas alternando o pipeline que irão ocupar. Caso não seja possível enviar uma instrução para cada pipeline, apenas uma instrução é enviada para execução por ciclo. Todas as instruções SPU operam em cima de registradores. Não há instruções acessando diretamente o LS e não há cache. Já o MFC é responsável pela movimentação e sincronização de dados e interface com o EIB. Ele é responsável por todos os controles de todas as formas de comunicação do SPE: DMA, mailboxes e sinais. Um dos conceitos por trás do MFC é as shopping lists, ou seja, o MFC torna possível que o programador especifique quantos e quais dados buscar num determinado momento. O programador pode buscar todos os dados que irá utilizar no processamento SPU de uma vez só, eliminando a sobrecarga que seria causada, por exemplo, pelo uso de cache, que buscaria dado por dado na memória principal quando ele fosse acessado a primeira vez, pelo menos. Além disto, o MFC é capaz de processar e executar comandos de DMA em paralelo com o fluxo de execução da SPU. Ou seja, práticas como double-buffering e multi-buffering fazem com que seja possível buscar o próximo dado a ser processado na SPU enquanto está processando o dado atual. O que torna um aumento considerável de performance de processamento do processador Cell.
  • 8. O LS é isolado da memória principal, ou seja, ele não se comporta como um cache e não aceita tags nem prefetch. Não é necessária tradução de endereços para o acesso ao LS já que o sistema operacional multiusuário roda apenas na PPU. Mas é importante dizer que é possível mapeá-lo no espaço de endereçamento da memória principal de forma que o PPE possa enxergar esta memória como se ela fosse parte da memória principal. No entanto, mesmo assim, todos os acessos ao Local Store são feitos por intermédio do MFC. O que acontece é que, quando este mapeamento está ligado, o PPE acessa o Local Store de forma transparente com a ajuda do MFC. No entanto, mesmo com este mapeamento ligado, uma SPU continua só tendo acesso à sua própria Local Store e continua responsável pela coerência de sua memória. Ou seja, caso ela queira acessar a um dado na memória principal ou no Local Store de outra SPU, ela terá que fazer isso através dos comandos providos pelo MFC. Por último, apesar de o LS não se comportar por padrão como um cache, é possível adicionar este suporte através de um cache gerenciado por software. 2.3 EIB O Element Interconnect Bus (EIB) é o elemento de comunicação entre os 9 núcleos de um processador Cell BE e os barramentos externos de memória e I/O. Ele é formado por uma estrutura de quatro anéis conectando os vários elementos dentro do processador Cell e pode chegar a uma taxa de transferência interna de até 300 GB/s. Dois destes anéis transferem dados no sentido horário e dois deles no sentido anti-horário. Os quatro anéis trabalham de forma que as transferências que estejam ocorrendo em um deles não interfiram eventuais transferências que estejam ocorrendo simultaneamente em algum dos outros anéis. Além disso, o árbitro central do barramento permite que até três transferências simultâneas ocorram no mesmo anel desde que elas não necessitem utilizar o mesmo pedaço de caminho dentro do anel. 3. Cell Broadband Engine Roadmap Como vimos o processador Cell consegue entregar um alto poder de processamento. No entanto, existem planos para expansão deste modelo. Além da evolução óbvia de se tentar colocar mais núcleos PPE e SPE dentro de um mesmo processador, também existem dois outros pontos que tendem a evoluir no futuro próximo. A primeira delas é relacionada ao suporte a operações vetoriais de ponto flutuante de precisão dupla nas SPUs. Apesar de tais operações já serem possíveis hoje, elas não são totalmente pipelined e parte delas é feita por emulação em software. Isto ocorre porque não há na SPU uma unidade funcional capaz de executar em hardware operações de ponto flutuante de precisão dupla. Basicamente a arquitetura não tem este suporte porque, para o propósito original do processador Cell BE que era atender à demanda do mercado de console de jogos equipando o PlayStation 3, este tipo de operação não é importante pois não é demandada tamanha precisão em software de jogos. No entanto, para as novas aplicações para as quais o Cell está sendo apontado, este tipo de precisão pode ser importante. Desta forma, existe a perspectiva de se ter no futuro
  • 9. um Cell BE equipado com SPUs que tenham suporte completo em hardware para operações com ponto flutuante de precisão dupla. Além disso, outra questão importante na evolução do Cell é a possibilidade de se colocar na PPU um processador PowerPC de última geração, com capacidade de processamento equivalente à de um processador PowerPC monocore ou multicore homogêneo. Na figura 4 mostramos uma perspectiva de evolução possível para a arquitetura Cell BE: Figura 4: Perspectiva de evolução da arquitetura Cell BE nos próximos anos (Referência IBM). 4. Cell SDK 2.1 O Cell SDK 2.1 provê suporte ao desenvolvimento de aplicações para arquitetura Cell em outras plataformas através de um ambiente de cross-development. O ambiente usado para o desenvolvimento é chamado de host e o ambiente target, neste caso, é uma máquina Cell ou um simulador de Cell. Como ambientes host são suportados: x86, x86_64, ppc64 e Cell rodando Fedora Core 6. Alguns dos componentes do Cell SDK 2.1 são: Compiladores e ferramentas GNU PPU e SPU (gcc, ld, combined gdb); Compiladores XL C/C++ PPU e SPU (incluindo suporte a auto-SIMD); IBM Cell System Simulator; SPU Timing; FDPR-Pro; Cell IDE, baseado em Eclipse/CDT; Bibliotecas MASS/V (para PPU e SPU) e SIMD Math;
  • 10. Várias bibliotecas e exemplos com um ambiente pré-configurado para o build de aplicações para Cell. O Cell SDK 2.1 pode ser baixado do IBM AlphaWorks e do Barcelona Supercomputing Center. É interessante notar que o simulador de Cell que acompanha o Cell SDK 2.1 torna possível que o desenvolvimento de aplicações para Cell seja feito de forma completa mesmo que não se tenha uma máquina com processador Cell BE disponível. A IBM Cell System Simulator é capaz de simular a funcionalidade de todos os componentes da arquitetura Cell BE e é capaz de simular também os SPEs e as transferências de DMA temporalmente, de forma que é possível obter, inclusive, informações valiosas de performance da execução de uma aplicação usando o simulador. Muitas vezes, as informações captadas pelo simulador seriam muito difíceis de se obter mesmo usando um hardware real. Outro ponto importante e que pode ajudar bastante principalmente os iniciantes na programação para Cell é o Cell IDE. A interface gráfica fornecida já tem integração com os compiladores e outras ferramentas necessárias para o build de projetos Cell, inclusive com suporte para build automático de aplicações que rodam tanto no PPE quanto no SPE que serão comentadas nas seções seguintes. O Cell IDE fornece também integração com o simulador e deploy automático de aplicações em um simulador local ou remoto ou mesmo em uma máquina Cell real, com capacidade de debug remoto da aplicação. 5. Modelos de Programação para o Cell Devemos nos perguntar antes de iniciar o processo de programação neste novo paradigma de programação multicore para Arquitetura Cell Broadband Engine: o que é necessário para o modelo de programação no Cell BE? Vejamos algumas características importantes para este modelo de programação: Capacidade de processamento massivamente paralelo: devem-se explorar todos os 18 dispositivos assíncronos do Cell BE através de delegação de tarefas ou computação paralela, como, por exemplo, intercalando transferência de dados através de DMA com computação. A distribuição do código deve levar em conta a especialização de cada núcleo: código de controle para o PPE e código de processamento massivo de dados para os SPEs. Vetorização: é importante explorar o paralelismo de dados. Largura de banda de alto desempenho. Recursos distribuídos. Programador possui uma sistemática da arquitetura e um custo efetivo do Framework para aplicar os recursos do Cell a uma classe específica de aplicações. Modelo de programação suporta vários construtores de linguagens, runtime, bibliotecas, ou Frameworks orientados a objeto.
  • 11. Focando-se em como uma aplicação pode ser particionada entre os elementos de processamento (PPE e SPE's) existem algumas considerações relevantes na programação do Cell [7]: 1. Processamento baseado em carregamentos (como em uma arquitetura load/store). 2. Movimentação de dados e código via DMA (Direct Memory Access). 3. Estrutura do programa. 4. Fluxo de dados. 5. Carga do barramento. É sempre importante lembrar que um arquiteto não deve começar o desenvolvimento de aplicações para Cell BE pensando nestas características a partir de suas premissas mais básicas. Já existe uma pilha de software completa disponível para a plataforma Cell BE cujo propósito é justamente facilitar o trabalho das pessoas escrevendo aplicações para esta plataforma. O que torna mais fácil a aderência de um programa às características acima e, conseqüentemente, tornando mais fácil a obtenção de bons ganhos em capacidade de processamento. Na figura 5 mostramos a pilha de software já existente no ambiente de desenvolvimento de aplicações para processadores Cell BE. Figura 5: Pilha de software para plataforma Cell BE. Com a devida atenção a estas características e com o seu uso adequado é possível se obter ganhos super lineares no poder de processamento em relação a arquiteturas convencionais.
  • 12. O processador Cell BE suporta uma variedade imensa de modelos de programação. Segundo J. A. Kahle et al. [9], em seu artigo de introdução à arquitetura Cell no IBM JRD (Journal of Research and Development), os modelos de programação são: 5.1. Modelo “Function Offload” Neste modelo, a aplicação principal é executada na PPE, invocando funções otimizadas que rodam em uma ou mais SPE's. Atualmente, o programador identifica estaticamente quais as funções podem ser executadas na PPE, e quais são executadas na SPE. 5.2. Modelo de Dispositivo Extendido O modelo de dispositivo extentido é um tipo especial da função “offload”. A SPE prove a função previamente disponibilizada pelo dispositivo, atuando como interface inteligente para o dispositivo externo. Este modelo utiliza as técnicas de “Mailboxes” ou mapeamento de memória da SPE acessível aos registradores, entre a PPE e a SPE através de comando / resposta FIFO. 5.3. Modelo de Aceleração Computacional Este modelo é centrado na SPE que prove mais granularidade e uso integrado das SPE's por uma aplicação ou ferramentas de programação. O software PPE atua como controle e disponibiliza um sistema de serviço para o software SPE. Técnicas de paralelização podem ser utilizadas para distribuir o trabalho acerca de múltiplas SPE's, executando em paralelo. 5.4. Modelo Stream Neste modelo, a SPE suporta passagem de mensagem da PPE para SPE. Existe um fluxo contínuo de dados enfileirados, sendo executados em paralelo pelas múltiplas SPE's, chamadas também de núcleos de processamento (kernel computacional). No caso do modelo de streaming, os núcleos de processamento em geral são todos iguais e os dados são divididos entre eles e processados em paralelo. Outra alternativa que pode ser usada é relacionada a este modelo, fazendo com que os núcleos computacionais diferentes atravessem um determinado dado através de todos os núcleos. Neste caso ter-se-ia um modelo pipeline. 5.5. Modelo de Memória Compartilhada Neste modelo, o acesso a dados são feitos de forma randômica através de seus endereços. Há suporte a variáveis compartilhadas. Através do mecanismo de bloqueio, vários programas SPE's podem acessar objetos da memória compartilhada localizados no espaço de endereçamento efetivo. O Centro de Super Computação em Barcelona (BSC), desenvolveu um compilador que suporta extensões parecidas com OpenMP [10]. A diferença básica na programação é que o
  • 13. OpenMP padrão usa variável global e o compilador OpenMP para Cell usa variável privada devido a existência das SPE's. 5.6. Modelo “Asymetric Thread Runtime” Neste modelo, os processos podem ser escalonados entre a PPE e as SPE's, similar a uma arquitetura SMP (Symetric Multiple Processing) convencional. Várias políticas de escalonamento podem ser aplicadas para os dois processos, seja PPE ou SPE, para otimizar o desempenho e a utilização do uso das SPE's. 5.7. Outros modelos É importante lembrar que além dos modelos vistos acima, outro modelos podem ser aplicados também. Por exemplo, todos os modelos já disponíveis para programação em arquiteturas monocore ou em arquiteturas com suporte a Simultâneos Multi-threading (SMT) podem ser aplicados de forma isolada a programas rodando no PPE. Da mesma forma, todos os modelos convencionais de programação paralela podem ser aplicados à PPE e suas SPEs. Outra alternativa muito usada é o encapsulamento de funções críticas em bibliotecas que rodam códigos nas SPEs, mas que são ligadas a programas PPE já que esta característica é permitida pela plataforma de software da arquitetura Cell BE. Desta forma, os desenvolvedores não precisam reescrever seus códigos que já rodam em PowerPC e, para que o código rode de forma otimizada na plataforma Cell BE basta que ele seja novamente ligado à biblioteca com código otimizado para aproveitar o paralelismo provido pela arquitetura. Um exemplo prático de uso deste paradigma é o desenvolvimento de jogos, onde boa parte do trabalho é delegada a uma biblioteca de OpenGL, por exemplo. Neste caso, o mesmo jogo é capaz de rodar em um processador Cell BE ou em outro processador, bastando para tal que o código seja recompilado utilizando a biblioteca otimizada de OpenGL para uma determinada arquitetura. É interessante ter em mente que o núcleo SPE é capaz de processar apenas uma thread por vez, de forma que se o programador quiser simular algo parecido com várias threads executando em um núcleo SPE ele terá que programar também um pequeno kernel no SPE que faça o escalonamento de suas tarefas. É importante lembrar também que os programas SPE podem ocupar apenas o espaço físico de 256 KB provido pelo Local Store para dados e instruções. Caso haja necessidade de programas maiores que 256 KB no SPE, o programador da aplicação terá que utilizar técnicas de desenvolvimento de aplicativos que o possibilitem carregarem apenas partes do código de cada vez nas SPEs, por exemplo, pelo uso de overlays ou apenas parte dos dados a serem processados por vez, como, por exemplo, através do uso de técnicas de software cache. Estas duas técnicas, overlays e software cache, são suportadas por padrão pelo Cell BE SDK, que provê em sua pilha de software bibliotecas que facilitam o uso destas funcionalidades.
  • 14. De forma geral, os modelos de programação servem de um bom guia para se iniciar o desenho de aplicações para plataformas Cell BE. No entanto, é bom sempre lembrar que o que vimos são apenas linhas mestras: misturar modelos de programação pode ser necessário e algumas vezes, até, aplicações específicas exigem modelos de programação diferentes dos vistos aqui. O importante é escolher o modelo correto, pois isso influenciará diretamente no tempo de desenvolvimento e na eficiência da aplicação final.
  • 15. Capítulo 2: Programando com Cell SDK 3.0 1. Introdução Como estudamos, a arquitetura Cell Broadband Engine é considerada heterogênea devido aos nós de processamento ser heterogêneos. O elemento de processador Power (PPE) é baseado no processador PowerPC com conjunto de instruções extendidas SIMD / Vetoriais através do VMX. Já o elemento processador sinergístico (SPE) executa instruções SIMD de forma direta. Portanto, como o conjunto de instruções é diferente, para cada programa desenvolvido em PPE ou SPE, existe um compilador especifico para ambos [11]. Um dos objetivos dos compiladores é explorar novos estilos de programação. O compilador oferece vetorização automática, mas também possui características internas para dar acesso direto à funcionalidade SIMD dos processadores. Os compiladores tanto para PPE quanto para unidades SPE são altamente otimizados para as seguintes linguagens: C, C++, Fortran [12, 13]. O paralelismo heterogêneo é a chave para a base do compilador. Os co-processadores (SPE’s) não executam o mesmo conjunto de instruções. A PPE é baseada na arquitetura PowerPC, mas os SPE’s não, gerando a necessidade de tratamento especial do compilador tais como: não há suporte a predição de desvio de hardware, arquitetura não orientada a múltiplos processos, único nível de memória. Este tratamento do compilador faz com que ele contenha compiladores para PPE e SPE. O compilador para plataforma Cell BE introduz algumas especificações OpenMP e outras do compilador IBM XL. Foi desenvolvido o compilador XL C especialmente para arquitetura Cell, disponível para avaliação no AlphaWorks [14]. Atualmente, o ambiente de desenvolvimento para plataforma Cell chegou a sua versão estável chamada “Software Development Kit for Multicore Acelleration version 3”. Tanto hardware quanto o software passaram por inúmeras versões até chegar à sua versão estável. Para entendermos os modelos de programação para plataforma Cell, devemos conhecer os recursos de programação. A princípio, temos: Recursos Computacionais: 2. 1PPE e 8 SPE cores; 3. Máquina SIMD; 4. 256 KB para Armazenamento Local (Código + Dados). Recursos de Comunicação: Barramento de Interconexão de 98B/ciclo; SPE DMA;
  • 16. Granularidade e latência de DMA; Sincronização Neste capítulo, apresentaremos como desenvolver um código para Cell Broadband Engine, introduzindo o ambiente de desenvolvimento provido pelo Cell SDK 3.0 e o IDE baseado em Eclipse para o Cell SDK. Demonstraremos como criar projetos Hello_SPU e Hello_PPU, como compilar e debugar a aplicação no Cell System Simulator. Neste novo ambiente de desenvolvimento Cell SDK 3.0 tiveram várias novidades nos procedimentos de instalação através do gerenciar de pacotes SDK – Pirut GUI [15] e do comando YUM, bem como adição e atualizações dos compiladores para Cell (como por exemplo: FORTRAN, Ada, XL/C++). Além de o sistema operacional ser baseado na distribuição do Linux Fedora 7 para pesquisadores e para dar continuidade a desenvolvimento de software open-source. Em outubro deste ano (2007), será disponibilizado o suporte do Cell SDK 3.0 para desenvolvimento comercial com suporte Linux Red-Hat 6. 2.1 Requisitos de Hardware / Software Para iniciarmos o desenvolvimento dos projetos no Eclipse para o Cell SDK 3.0, devemos checar se todos os requisitos de hardware e software estão devidamente instalados e configurados no sistema. O Cell SDK 3.0 suporta as seguintes plataformas: x86, x86_64, PPC64, IBM Blade QS20, IBM Blade QS21. É recomendável que se tenha no mínimo 5GB de espaço livre em disco e 1GB de RAM para instalar todos os pacotes e ferramentas de desenvolvimento. Com relação aos requisitos de software, há vários procedimentos para instalação do Fedora 7, instalação de pacotes previa (preparação para instalar o Cell SDK 3.0) e dependências de software. No minicurso em questão, não entraremos em detalhes de instalação de hardware e software. Forneceremos este material através do material do minicurso (DVD) e pelo Portal CellBR [16] que possui a missão de divulgar a tecnologia Cell, promovendo o desenvolvimento de software open-source, ferramentas de desenvolvimento, aplicações para processamento de imagens e pesquisas. O grupo PAD em parceria com a IBM Brasil está desenvolvendo o YUM Server para armazenar todos os pacotes RPM's para o Brasil sem a necessidade de realizar download do BSC. Na instalação do Fedora 7, recomenda-se a não instalação do Eclipse Fedora, e providenciar a versão 2.2 da IDE Eclipse através do download na Web site do Eclipse org. [17]. Para o suporte à criação de projetos no ambiente C/C++, a instalação do CDT 3.1 deve ser instalada. Outra recomendação importante é fazer download do Java SDK 1.4.2 apenas do site da SUN ou da IBM e configurá-lo adequadamente no sistema para a versão pré-instalada do Fedora 7 não interfira no sistema.
  • 17. 2.2 Criando Projetos no Eclipse Para rodar o Eclipse 3.2, basta clicar em aplicações na barra de ferramentas, programação, eclipse. Ou simplesmente digitar na linha de comando: /opt/cell/ide/eclipse > ./eclipse Para utilizar o Cell SDK 3.0, temos que checar em atualizações de software se o Eclipse Platform Runtime e o CDT estão devidamente instalados. Inicialmente, modificamos a perspectiva do ambiente de desenvolvimento para criar projetos em C/C++, como apresentado na figura a seguir: Figura 06: Modificar a perspectiva do Ambiente de Desenvolvimento
  • 18. Inicialmente, apresentaremos a criação de um projeto SPU com o make gerenciado. Caso o usuário deseje desenvolver seu próprio makefile, poderá consultar o makefile padrão do exemplo “simple” do tutorial do próprio Cell SDK 3.0 no seguinte diretório: /opt/cell/sdk/src/tutorial/simple Figura 07: Criando um novo Projeto com C Managed Make Nomeamos o nosso projeto de SPU e selecionamos um compilador para SPU executável.
  • 19. Figura 08: Selecionar o Cell SPU executável Finalizando a criação do Projeto SPU, temos de configurar as propriedades do projeto como: 1. Inserir o caminho do diretório Veja na figura 09, o caminho do diretório a ser inserido na propriedade do projeto. /opt/cell/sysroot/opt/cell/sdk/usr/spu/include
  • 20. Figura 09: Caminho do Diretório do include da SPU Neste momento criamos um arquivo hello_spu.c escrevendo o seguinte código: #include <stdio.h> #include <profile.h> int main(unsigned long long id) { //prof_clear(); //prof_start(); printf("WSCAD2007: Hello World (0x%llx)n", id); //prof_stop(); return 0; } Salvando o código, o projeto SPU é compilado. Dando continuidade, criamos o projeto PPU com o SPU embutido. Selecionamos novo projeto com o compilador Cell PPU executável e o SPU embutido.
  • 21. Figura 10: Criação do Projeto PPU Quanto às propriedades do Projeto PPU, iremos configurar os seguintes parâmetros: 1. A entrada da PPU GNU 32 bit Embed SPU (/root/workspace/SPU/hello_spu) 2. Inserir o link para biblioteca -libspe2 Na figura 11, apresentamos como configurar o caminho para o Input do PPU link. E na figura 12, como inserir a biblioteca libspe2. Figura 11: Inserir o Input do PPU link Figura 12: Inserir a biblioteca libspe2
  • 22. A próxima etapa é escrever o código para PPU, descrito a seguir: #include <stdlib.h> #include <stdio.h> #include <errno.h> #include <libspe2.h> #include <pthread.h> extern spe_program_handle_t SPU; #define SPU_THREADS 8 void *ppu_pthread_function(void *arg) { spe_context_ptr_t ctx; unsigned int entry = SPE_DEFAULT_ENTRY; ctx = *((spe_context_ptr_t *)arg); if (spe_context_run(ctx, &entry, 0, NULL, NULL, NULL) < 0) { perror ("Failed running context"); exit (1); } pthread_exit(NULL); } int main() { int i; spe_context_ptr_t ctxs[SPU_THREADS]; pthread_t threads[SPU_THREADS]; /* Create several SPE-threads to execute 'SPU'. */ for(i=0; i<SPU_THREADS; i++) { /* Create context */ if ((ctxs[i] = spe_context_create (0, NULL)) == NULL) { perror ("Failed creating context"); exit (1); } /* Load program into context */ if (spe_program_load (ctxs[i], &SPU)) { perror ("Failed loading program"); exit (1); } /* Create thread for each SPE context */ if (pthread_create (&threads[i], NULL, &ppu_pthread_function, &ctxs[i])) { perror ("Failed creating thread"); exit (1); } } /* Wait for SPU-thread to complete execution. */ for (i=0; i<SPU_THREADS; i++) { if (pthread_join (threads[i], NULL)) { perror("Failed pthread_join"); exit (1); } /* Destroy context */ if (spe_context_destroy (ctxs[i]) != 0) { perror("Failed destroying context"); exit (1); } } printf("nThe program has successfully executed.n"); return (0);}
  • 23. A biblioteca libspe2.h é a referência para a SPE Runtime Management Library que está na versão 2.2 no SDK 3.0. Mais informações sobre como usar esta biblioteca estão no documento "SPE Runtime Management Library Version 2.2 Draft" [17] que está em /opt/cell/sdk/docs/lib depois que o SDK 3.0 é instalado. A estrutura de dados spe_program_handle_t guarda as informações a respeito de um programa SPE que é encapsulado dentro de um programa PPE. #define SPU_THREADS 8 void *ppu_pthread_function(void *arg) { Está função é criada para ser a função executada nas threads criadas com a biblioteca pthreads da PPE. O único propósito dela neste programa exemplo é iniciar a execução das threads SPE. É necessária a criação destas threads PPE porque sempre que uma thread SPE é criada por um programa PPE, a thread do programa PPE fica bloqueada na chamada spe_context_run. Desta forma, se você estiver desenvolvendo um programa PPE e SPE em que a parte PPE crie e gerencie diversas threads SPEs, você vai ter que criar uma thread PPE para gerenciar cada uma das threads SPE criadas para que o programa PPE não fique travado na criação da primeira thread SPE. Você pode pensar em uma analogia que quando você faz uma chamada spe_context_run, a thread sendo executada transforma de uma thread PPE para uma thread SPE. Se você não tiver criado uma thread PPE específica para se "transformar" em uma thread SPE, seu programa PPE inteiro se "transformará" apenas em uma única thread SPE e você não terá oportunidade de criar outras threads SPE até que a primeira termine e retorne. spe_context_ptr_t ctx; Esta estrutura de dados spe_context_ptr aponta para o contexto de uma SPE. O contexto de uma SPE é formado pelo seu Local Store e pelo seu MFC problem state. unsigned int entry = SPE_DEFAULT_ENTRY; ctx = *((spe_context_ptr_t *)arg); if (spe_context_run(ctx, &entry, 0, NULL, NULL, NULL) < 0) { A chamada spe_context_run pede ao sistema operacional que ele aloque uma SPE para rodar o programa SPE carregado no contexto indicado e inicie seu processamento. perror ("Failed running context"); exit (1); } pthread_exit(NULL); } int main() { int i; spe_context_ptr_t ctxs[SPU_THREADS]; pthread_t threads[SPU_THREADS]; /* Create several SPE-threads to execute 'SPU'. */ for(i=0; i<SPU_THREADS; i++) {
  • 24. /* Create context */ if ((ctxs[i] = spe_context_create (0, NULL)) == NULL) { A função spe_context_create cria um contexto SPE que poderá ser, posteriormente, escalonado em uma SPE física. perror ("Failed creating context"); exit (1); } /* Load program into context */ if (spe_program_load (ctxs[i], &SPU)) { A chamada spe_program_load carrega um programa SPE em um contexto já criado para que, quando este contexto for escalonado para execução, a aplicação carregada nele seja executada. perror ("Failed loading program"); exit (1); } /* Create thread for each SPE context */ if (pthread_create (&threads[i], NULL, &ppu_pthread_function, &ctxs[i])) { Criação das threads PPE que executarão o código da função ppu_thread_function que, como já explicado, é o código que irá chamar spe_context_run para escalonar os contexto criados em SPEs físicas. perror ("Failed creating thread"); exit (1); } } /* Wait for SPU-thread to complete execution. */ for (i=0; i<SPU_THREADS; i++) { if (pthread_join (threads[i], NULL)) { Espera-se que cada thread PPE retorne (o que implicitamente significa que cada thread SPE também terá finalizado seu trabalho, já que as threads PPE ficaram bloqueadas na chamada spe_context_run presente em ppu_thread_function). perror("Failed pthread_join"); exit (1); } /* Destroy context */ if (spe_context_destroy (ctxs[i]) != 0) { spe_context_destroy destrói os contextos criados e libera a memória usada por eles. perror("Failed destroying context"); exit (1); } } printf("nThe program has successfully executed.n"); return (0); }
  • 25. No ambiente Cell, iremos criar um simulador local e configurá-lo. O simulador pode rodar em diversos ambiente como: janela de controle, TCL console, Linux console e diretório de trabalho. Figura 12: Propriedades do Simulador Cell Local Pode ser que o simulador não reconheça a configuração de rede (quando configurado para DHCP). Para criar o simulador Cell no ambiente Eclipse, é preciso configurar o DNS da rede. Depois de rodar o simulador, é preciso depurar a aplicação, criando um novo “Cell C/C++ Target Application”, como apresentado na figura 13 e 14: Figura 13: Ambiente de depuração
  • 26. Figura 14: Criação do novo C/C++ Cell Target Application Na configuração desta aplicação, normalmente já vem selecionado o nome do projeto selecionado para depuração. O próximo passo, é inserir o projeto executável como demonstrado na figura 15: Figura 15: Seleção do projeto executável A seguir, na figura 16, configuramos o Debugger para Cell BE gdbserver gdb/mi e incluimos o caminho do diretório para o servidor, localizado em /opt/cell/toolchain/bin/ppu-gdb. Quando acionamos o Debug o servidor gdbserver é chamado através do endereço IP configurado para HOSTNAME.
  • 27. Figura 16: Configuração do Debugger Neste diretório indicado para selecionar o servidor gdbserver há várias opções de servidores para debuggers específicos para PPU e SPU, e também quanto ao tipo de arquitetura. Para ajudar o processo de Debug, no Cell SDK 3.0, temos a ferramenta de desempenho de Debug (“Performance Debugging Tool”) que apresenta um visualizador da saída do trace. Outra ferramenta de desempenho (FDPR-Pro) externa ao simulador é interessante por otimizar a execução dos projetos PPU/SPU executável. Estas duas ferramentas são estudadas em detalhes no guia do programador [18]. Para finalizar esta demonstração, apresentaremos uma análise de desempenho fazendo uso do “dynamic profiling”. Esta ferramenta será utilizada no código SPU. Observando o código escrito, destacamos três linhas comentadas para as funções: prof_clear(), prof_start(), e prof_stop(). Descomentamos estas linhas e salvamos o código. E depois recompilamos novamente o projeto PPU. Na janela do simulador, podemos iremos modificar o “SPU mode” para o modo pipeline, como apresentado na figura 17: Figura 17: Modificar o SPUmode
  • 28. Finalizando este procedimento, rodamos a aplicação PPU através: Run -> Run History -> PPU. Agora, podemos analisar as estatísticas na janela do simulador no SPE0. Figura 18: Visualização das Estatísticas do Simulador No capítulo 4, estas ferramentas serão apresentadas com mais detalhes
  • 29. Capítulo 3: Programando para Cell BE: DMA, Mailboxes e SIMD 1. Introdução Como vimos anteriormente, a arquitetura Cell BE provê uma série de mecanismos para orquestrarmos os diferentes elementos de processamento paralelo disponíveis. Estes mecanismos de coordenação são essenciais no desenho de plataformas multicore pois são eles que permitem o controle das concorrências entre as diversas tarefas sendo executadas nos diversos elementos de processamentos da arquitetura. No caso da arquitetura Cell BE, os principais mecanismos de sincronização existentes são os Mailboxes e as transferências de dados por DMA. Outros elementos existentes como eventos e sinais não serão discutidos neste mini-curso introdutório. Além disso, a arquitetura Cell BE fornece unidades de execução vetorial em todos os seus elementos de processamento. É importante que alguém programe para esta arquitetura tenha ciência disto e tente usar estas unidades de execução vetorial sempre que possível. No caso de programas PPE o uso de instruções vetoriais pode trazer ganhos consideráveis pelo uso do paralelismo de dados. Já nos programas SPE, o uso de instruções vetoriais é praticamente mandatório, já que este núcleo foi projetado como um elemento de processamento intrinsecamente vetorial. Nas seções seguintes, apresentaremos detalhadamente destes três elementos básicos da programação para a arquitetura Cell BE e explicar um exemplo prático de multiplicação de matrizes fornecido junto com o Cell BE SDK. 2. DMA Antes de falamos sobre DMA propriamente dito, precisamos entender um pouco melhor os Memory Flow Controllers (MFC). Todos os elementos de comunicação disponibilizados pela arquitetura Cell BE são controlados, em última instância, pelos MFCs de cada SPE. Estes MFCs funcionam praticamente como núcleos extras da arquitetura pois são capazes de executar suas atividades de comunicação de forma paralela à execução de código das SPEs. Para se iniciar qualquer uma das formas de comunicação (DMA, mailbox, sinais e eventos), é necessário que sejam gerados comandos para o MFC. Estes comandos podem ser gerados basicamente de duas formas: um código rodando no SPE executa uma série de escritas e/ou leituras no seu canal de instruções; ou um código rodando no PPE ou em outros dispositivos faz uma série de stores e/ou loads em registradores do MFC mapeados em memória. Os comandos do MFC são enfileirados em duas filas independentes: MFC SPU Command Queue, para os comandos associados à SPU iniciados pelo canal de controle; e MFC Proxy Command Queue, para comandos iniciados pelo PPE ou por outro dispositivo através dos
  • 30. registradores mapeados em memória. É interessante dizer ainda que há suporte a alguns comandos atômicos no MFC. O DMA é o meio existente para transferir grandes quantidades de dados e instruções de forma eficiente entre o LS e a memória principal. No entanto, pode-se usar DMA para a transferência de pequenas quantidades de dados também. Comandos de DMA nada mais são que comandos de MFC que transferem dados, sendo que a direção da transferência é sempre em relação ao SPE mesmo que o comando MFC tenha sido gerado através de escritas e/ou leituras nos registradores do MFC mapeados em memória pelo PPE ou por outro dispositivo. Ou seja, quando estamos transferindo um dado para o SPE (da memória principal para o LS), o prefixo do comando de DMA é get. Já quando estamos transferindo um dado do SPE (do LS para a memória principal), o prefixo do comando de DMA é put. Apesar de ser possível iniciar um DMA através de diversas escritas e/ou leituras nos canais de instrução do SPE ou nos registradores mapeados em memória do MFC, o Cell SDK 2.1 fornece uma série de macros de mais alto nível que agrupam estas escritas e/ou leituras de forma a facilitar a vida de quem precise realizar DMAs no Cell. Estes macros são definidos no arquivo spu_mfcio.h. Por exemplo, existem macros já definidas para iniciar um get ou um put através de DMA passando apenas as regiões de memória de interesse, basicamente. Sempre que possível, os DMAs devem ser iniciados dos SPEs pois assim ter-se-á uma maior performance nas transferências. Existem basicamente dois motivos para esta melhor performance de DMAs iniciados pelo SPE. Primeiro porque independente de onde o DMA esteja sendo criado, ele vai ser executado pelo MFC do SPE. Ou seja, se o PPE estiver iniciando um DMA, na verdade ela vai requisitar os dados ao MFC e o MFC irá realizar a transferência. Quando uma SPU requisita um DMA ao MFC, ele o faz através de sucessivas leituras/escritas nos canais de instrução do SPE, cujo acesso é mais rápido que o dos registradores do MFC mapeados em memória utilizados pelo PPE para requisitar o mesmo DMA ao MFC. Depois porque existe um maior número de SPEs que de PPE. Se todos os DMAs forem originados pelo PPE, haverá um gargalo neste ponto. Já se eles forem originados dos SPEs, o trabalho de preparação do DMA será distribuído nos recursos disponíveis no processador Cell. Como já visto, o MFC é capaz de processar e executar comandos de DMA em paralelo com o fluxo de execução da SPU. Ou seja, práticas como double-buffering e multi-buffering fazem com que seja possível buscar o próximo dado a ser processado na SPU enquanto se está processando o dado atual, aumentando ainda mais a performance de processamento do processador Cell. Algo extremamente importante de ser lembrado no caso dos DMAs é que os comandos de DMA não necessariamente são executados em ordem. Para assegurar a ordem de execução das requisições DMA o MFC disponibiliza dois tipos de sincronizações: fence e barrier. Os comandos fenced são aqueles em que todos os comandos de DMA antes dele com o mesmo tag group devem terminar antes deste, e comandos executados depois dele também podem terminar
  • 31. antes dele. Já os comandos barrier são aqueles em que ele e todos os comandos de DMA depois dele com o mesmo tag group não são executados até que todos os comandos anteriores com este tag group estejam completos. Figura 19 – fence e barrier nas transferências de DMA (Referência IBM). As transferências de DMA podem ser de 1, 2, 4, 8, 16 e múltiplos de 16 bytes, até 16 KB por transferência. Para que os DMAs possam ocorrer, os dados a serem transferidos devem estar naturalmente alinhados se tiverem 1, 2, 4, 8 ou 16 bytes. Para transferências de tamanhos múltiplos de 16 bytes o alinhamento deve ser de, no mínimo, 16 bytes. Para melhor eficiência na transferência por DMA, os dados devem estar alinhados em 128 bytes já que este é o tamanho das linhas de cache no PPE. Os tag groups que identificam e agrupam as transferências de DMA variam de 0 a 31 (5 bits). O mesmo identificador pode ser usado em quantos comandos quanto se quiser. Este tag group também pode ser usado para se saber o status ou para esperar a finalização do comando de DMA, já que os comandos não são bloqueantes. O Cell BE também tem suporte à execução de listas de DMA. Estas listas de DMA são uma forma eficiente de se fazer transferência de dados que não sejam contíguos da ou para a memória principal. Num mesmo comando de DMA é possível especificar a lista de regiões de serão transferidas e, através de uma funcionalidade scatter-gather, uma lista com até 2 K requisições pode ser transferida no mesmo comando de DMA.
  • 32. Apesar de sempre falarmos que as transferências de DMA são feitas sempre entre memória principal e LS, também é possível transferências de dados por DMA entre SPEs, desde que esteja ativo o mapeamento dos LSs no espaço de endereçamento da memória principal. Desta forma, onde colocar um endereço da memória principal nos comandos de DMA pode-se colocar um endereço de memória principal que esteja mapeado para um LS de outro SPE. Existem artifícios internos à arquitetura que tornam possível para o PPE calcular o endereço mapeado na memória principal de uma variável de um LS. Este endereço pode ser passado por exemplo por mailbox para outro SPE que pode, então, fazer uma transferência de DMA utilizando este endereço mapeado no LS do primeiro SPE como origem ou destino. 3. Mailboxes Os Mailboxes são filas para trocas de mensagens entre os diversos componentes ligados aos EIB, ou seja, PPE, SPEs e também outros dispositivos de I/O conectados ao processador Cell, e os SPEs. As mensagens enviadas por Mailboxes possuem 32 bits. Cada SPE tem duas mailboxes de saída e uma de entrada. Devido ao pequeno tamanho das mensagens, os mailboxes são usados para atividades de controle entre os elementos do processador Cell. Olhando com mais detalhe cada uma das três mailboxes existentes no SPE, tem-se: PPE mailbox queue (SPU write outbound): A SPU escreve nesta mailbox e a PPU lê dela. Esta mailbox tem tamanho 1 e, caso a SPU tente escrever nela quando já haja uma mensagem, o programa SPU é bloqueado. Para evitar este bloqueio, o programa SPU deve conferir se este mailbox está vazia antes de escrever nela. Já a PPU deve verificar se tem alguma coisa para ler nesta mailbox antes de efetuar a leitura pois, caso não haja nada para ler, será retornado um valor qualquer na leitura. PPE interrupt mailbox queue (SPU write outbound): esta mailbox é semelhante à PPE mailbox queue descrita acima, com a diferença de que, quando o SPE escreve nela, ao invés de ser enviado uma mensagem para o PPE, é gerada uma interrupção. SPE mailbox queue (SPU read inbound): O PPE escreve nesta mailbox e o SPE lê dela. Este mailbox possui 4 entradas. Quando a PPU escreve nesta mailbox ela deve verificar antes se ela já não está cheia senão uma mensagem pode ser sobrescrita. Já a SPU deve verificar antes de ler desta mailbox se existe alguma coisa para ler, senão ela ficará bloqueada na leitura. 4. SIMD Além das funcionalidades descritas acima que facilitam a implementação de códigos combinados PPE e SPE tornando possível a orquestração destes elementos, também foram criadas extensões para as linguagens C e C++ para facilitar a programação SIMD ou vetorial para o processador Cell.
  • 33. Por exemplo, para o PPE, foram criados tipos de dados vetoriais com 128 bits e comandos vetoriais (intrinsics), que são comandos inline em assembly para serem usados diretamente no código C/C++. Os instrinsics PPE são divididos em três grupos: Specific intrinsics: são mapeados em uma única instrução assembly. Generic intrinsics: são mapeados em uma ou mais instruções assembly. Predicates intrinsics: comparam valores e retornam um inteiro que pode ser usado como um valor ou como resultado de uma instrução de branch. Os instrinsics VMX possuem o prefixo vec em frente ao mnemônico assembly que executa a mesma operação. Para a SPU também foram criados tipos de dados vetoriais com 128 bits e instrinsics. Os instrisics SPE são divididos nos seguintes grupos: Specific intrinsics: são mapeados em uma única instrução assembly. Generic intrinsics: são mapeados em uma ou mais instruções assembly. Composite intrinsics: formados de uma seqüência de Specific e Generic intrinsics. Os intrinsics SPU possuem o prefixo spu em frente ao mnemônico assembly que executa a mesma operação. É importante frisar que os tipos de dados e intrinsics suportados por PPE e SPE, apesar de terem muita coisa em comum, são diferentes. Em comum, por exemplo, eles têm o fato de que todas as operações são feitas em cima de dados com 128 bits (4 full-words, 8 half-word ou 16 bytes). A SPU ainda suporta 2 double-words. No caso da SPU, o uso de instruções SIMD é ainda mais crítico para a performance do núcleo já que, como foi dito anteriormente, a SPU é um processador intrinsecamente vetorial. Nele, apesar de ser possível o processamento escalar, este não aproveita toda a performance do processador já que mesmo o processamento escalar é feito com instruções vetoriais operando sobre vetores pois não existem instruções escalares na SPU. Além disto, as instruções escalares são bem executadas apenas se os dados escalares estiverem alocados nos chamados preferred slots do vetor, o que torna ainda mais penosa este tipo de operação na SPU. Caso o dado escalar não esteja em um preferred slot, haverá uma sobrecarga para transferência deste dado para este preferred slot, induzindo a uma performance menor no processamento da SPU. Abaixo são mostrados os preferred slots para processamento escalar nos vetores SPU:
  • 34. Figura 20 – Preferred Slots para dados escalares em registradores SPU. Existem técnicas de programação que podem ser usadas para diminuir o impacto da perda de performance descrita acima no processamento escalar nas SPUs. Por exemplo, pode-se tentar promover dados escalares a vetores, seja repetindo o mesmo valor em todas as posições e extraindo apenas um dos valores do vetor após o processamento, seja pelo agrupamento de vários escalares em um vetor e extração apenas de um dos valores por vez ao fim de cada processamento. Isto melhora a performance porque todo acesso a dado na SPU é feito através de loads e stores de 128 bits por vez. Com o uso de operações escalares, cada load ou store implicaria em uma adição de 3 outras instruções para posicionar o dado escalar no preferred slot. Caso se use uma das estratégias acima, estas 3 instruções serão economizadas e necessitar-se-á de apenas uma instrução adicional para extrair o resultado do vetor usado para fazer as operações. Além da vetorização de código que é feita pelo programador utilizando os intrinsics descritos acima, outra alternativa é o uso de auto vetorização sobre um código escalar tradicional. Para uso da auto vetorização, no entanto, é necessário o uso de um compilador que tenha tal funcionalidade de análise de código, como, por exemplo, o XL C/C++, distribuído pela IBM e que faz parte do Cell SDK 2.1. Esta funcionalidade, porém, é limitada, já que análise de códigos- fonte para auto vetorização não são simples e nem sempre obtém resultados muito bons. Caso se queira realmente tirar proveito do ganho de performance capaz de ser obtido através da vetorização do código, este trabalho deverá ser feito pelo programador através do uso de instruções SIMD. Outra questão interessante de ser dita em relação ao uso de tipos de dados vector, que são os tipos de dados criados para uso em instruções SIMD, é que apontadores de vector contam suas posições em memória de 16 em 16 bytes, já que este tipo de dados possui 128 bits. Ou seja, se declaramos vector float *p, então p + 1 apontará para uma posição de memória 16 bytes à frente. Além disto, é possível fazer cast entre apontadores de tipos de dados vetoriais e escalares. Por exemplo: float *a; vector float *b = (vector float *) a;
  • 35. é uma operação possível desde que o apontador de float tenha a memória apontada por ele alocada alinhada em 16 bytes, já que isto é requisito do tipo de dado vector. Quando uma variável do tipo vector é declarada, a região da memória alocada para ela é pré-alinhada em 16 bytes pelo compilador. Por último, é importante dizer que a vetorização de código não deve ser subestimada. O poder de processamento paralelo provido por ela, já que todas as operações são feitas simultaneamente sobre todos os dados dos vetores, sempre deve ser levado em consideração quando se está desenhando uma solução para um problema em processadores que suportem instruções SIMD como o Cell. Em muitos casos até, o uso de instruções vetoriais trás mais ganhos que o uso de técnicas de paralelização explícito do processamento em múltiplos núcleos. 4. Multiplicação de matrizes A título de exemplo de uso dos conceitos vistos acima iremos apresentar o exemplo de multiplicação de matrizes cujo código-fonte está disponível no IBM SDK for Multicore Acceleration 3.0. O algoritmo de multiplicação de matrizes é bem conhecido e é um exemplo típico de algoritmo facilmente paralelizável e que consegue grandes ganhos de desempenho através do uso de paralelismo nos seus cálculos. O programa de demonstração de multiplicação de matrizes do IBM SDK for Multicore Acceleration 3.0 está disponível dentro do arquivo /opt/cell/sdk/src/demos_source.tar. Expandindo este arquivo, que é instalado juntamente com a instalação do IBM SDK for Multicore Acceleration 3.0 através do pacote cell-demos-source, uma árvore de diretórios é criada. O exemplo de multiplicação de matrizes fica no diretório demos/matrix_mul relativo ao local onde o arquivo demos_source.tar foi expandido. Entrando no diretório demos/matrix_mul podemos ver que já existe neste diretório um exemplo completo do programa de multiplicação paralela de matrizes para ser rodado numa plataforma Cell BE. Este programa calcula C = A * B onde A, B e C são matrizes quadradas N x N de valores de ponto flutuante de precisão simples. O algoritmo usa particionamento em blocos para reduzir a banda de comunicação necessária para sua execução. O tamanho do bloco é fixado em 64. As SPEs controlam qual bloco processar através de um contador atômico unificado controlado através das funcionalidades de comunicação atômica providas pelo MFC e que não é foco deste mini-curso. O projeto disponível em demos/matrix_mul é completo, ou seja, caso se deseje é possível compilá-lo diretamente através da linha de comando usando-se os makefiles disponibilizados e as instruções em [11] na seção “Developing Code for the Cell Broadband Engine”. Existe ainda no arquivo README.txt deste diretório uma descrição completa da aplicação e de todas as opções de execução disponíveis. No entanto, conforme visto no Capítulo 2, o foco deste mini-curso é a utilização da Interface Integrada de Desenvolvimento baseada em Eclipse para a plataforma Cell BE. Para
  • 36. criarmos projetos dentro do Eclipse com os códigos-fonte fornecidos pelo exemplo de multiplicação de matrizes do IBM SDK for Multicore Acceleration, devemos seguir os seguintes passos: 1. Abra o Eclipse com os plug-ins do CDT e do IBM SDK for Multicore Acceleration IDE já instalados em um novo workspace onde você irá salvar os seus projetos. 2. Mude a perspectiva padrão do Eclipse para a perspectiva C/C++. Para isso acesse a opção Window -> Open Perspective -> Other... e escolha a perspectiva C/C++. 3. Através da opção File -> New -> Project... crie um projeto do tipo C -> Managed Make C Project com o nome block cujo tipo de projeto seja Cell SPU Executable. 4. Crie um novo arquivo de código-fonte dentro deste projeto block recém-criado através da opção File -> New -> Source File. Dê o nome de block.c para este arquivo. 5. Copie o conteúdo do arquivo demos/matrix_mul/spu/block.c para o arquivo block.c criado dentro do projeto block no seu workspace Eclipse. 6. Salve o arquivo block.c. Note que o build automático do Eclipse irá ser iniciado e alguns problemas de compilação serão encontrados no projeto pois o compilador não achará o arquivo matrix_mul.h. Assim que importarmos o projeto PPU resolvemos este problema. 7. Através da opção File -> New -> Project... crie um projeto do tipo C -> Managed Make C Project com o nome matrix_mul cujo tipo de projeto seja Cell PPU Executable e que referencie o projeto anteriormente criado block. 8. Crie um novo arquivo de cabeçalho dentro deste projeto matrix_mul recém-criado através da opção File -> New -> Header File. Dê o nome matrix_mul.h para este arquivo. 9. Copie o conteúdo do arquivo demos/matrix_mul/matrix_mul.h para o arquivo matrix_mul.h criado dentro do projeto matrix_mul no seu workspace Eclipse. 10. Salve o arquivo matrix_mul.h. 11. Crie um novo arquivo de código-fonte dentro do projeto matrix_mul através da opção File -> New -> Source File. Dê o nome matrix_mul.c para este arquivo. 12. Copie o conteúdo do arquivo demos/matrix_mul/matrix_mul.c para o arquivo matrix_mul.c criado dentro do projeto matrix_mul no seu workspace Eclipse. 13. Salve o arquivo matrix_mul.c. O build automático do Eclipse irá ser iniciado e vários problemas de compilação do projeto aparecerão. Para resolver estes problemas e os problemas anteriormente encontrados no projeto block, precisamos alterar as algumas configurações de build dos projetos. 14. Clique com o botão direito do mouse sobre o projeto block e escolha a opção Properties do pop-up menu. 15. Na janela que aparece, escolha C/C++ Build no lado esquerdo e, no lado direito mude a configuração para spu-gnu-release. 16. Ainda na janela de configuração das opções de build, clique no conjunto de opções Directories embaixo de SPU GNU C Compiler with Release Options. Na opção Include paths (-I) que aparecerá do lado direito da janela inclua o caminho para o projeto matrix_mul no seu workspace Eclipse. 17. Clique em OK para fechar a janela.
  • 37. 18. Clique com o botão direito do mouse sobre o projeto matrix_mul e escolha a opção Properties do pop-up menu. 19. Na janela que aparece, escolha C/C++ Build no lado esquerdo e, no lado direito mude a configuração para ppu-gnu32-release. 20. Ainda na janela de configuração das opções de build, clique no conjunto de opções Inputs embaixo de PPU GNU 32 bit Embed SPU. Na opção Embed SPU Inputs que aparecerá do lado direito da janela inclua o caminho para o executável SPU gerado no projeto block. Em geral este caminho pode ser representado por "${workspace_loc:/block/spu-gnu-release/block}". 21. Ainda na janela de configuração das opções de build, clique no conjunto de opções Libraries embaixo de PPU GNU 32 bit C Linker. Marque os checkboxes libspe2 (-lspe2), libpthread (-lpthread) e Math library (-lm). Inclua ainda na opção Libraries (-l) a biblioteca misc e a biblioteca numa. Na opção Library search path (-L) inclua o diretório /opt/cell/sysroot/opt/cell/sdk/usr/lib. 22. Após estas alterações o build automático do Eclipse irá ser iniciado e os dois projetos devem ser compilados sem erros. 23. Para lançar o projeto no ambiente simulado, basta iniciar o simulador de dentro do Eclipse e configurar o lançamento da aplicação matrix_mul conforme descrito no Capítulo 2, lembrando que na configuração do ambiente alvo deve ser ativada a variável LD_LIBRARY_PATH com o valor /opt/cell/sdk/usr/lib a fim de que o sistema operacional consiga carregar a biblioteca libmisc.so no ambiente simulado. A configuração desta variável pode ser feita através da aba Environment da configuração de execução de uma aplicação remota do tipo C/C++ Target Cell Application. A parte do programa que roda na PPU basicamente é responsável por inicializar as matrizes com dados randômicos, criar as threads SPE especificadas, enviar um mailbox para elas indicando que elas devem iniciar seu processamento e esperar que todo o trabalho seja concluído. Eventualmente, caso uma opção para isso seja especificada na execução do programa, a PPU irá também verificar se a conta feita pelas SPEs está correta. O programa SPE que roda em um ou mais núcleos é exatamente o mesmo. Inicialmente o programa reserva as tags de DMA que ele irá usar para suas transferências de dados; inicializa os buffers que irá utilizar para fazer double buffering a fim de aumentar o desempenho final da aplicação, já que como vimos no Capítulo 1 a arquitetura Cell BE permite que se faça simultaneamente nas SPEs a transferência de dados e a execução de código; pega os parâmetros de execução através da DMA e fica esperando a chegada de uma mensagem de mailbox enviada pelo PPE indicando que ele pode iniciar seu processamento. Assim que esta mensagem chega o programa SPU entra em loop fazendo a transferência do bloco de dados a processar a partir da memória principal e realizando o cálculo da multiplicação das células do bloco capturado utilizando-se código vetorizado através de instruções SIMD nativas do SPU.
  • 38. Capítulo 4: Análise de desempenho com IBM Cell BE full-system Simulator 1. Introdução Como já dissemos, o IBM Cell System Simulator torna possível que o desenvolvimento de aplicações para Cell possa ser feito de forma completa mesmo que não se tenha uma máquina com processador Cell disponível. Ele é capaz de simular a funcionalidade de todos os componentes da arquitetura Cell BE e é capaz de simular também os SPEs e as transferências de DMA temporalmente, de forma que é possível obter, inclusive, informações valiosas de performance da execução de uma aplicação usando o simulador. Muitas vezes, as informações captadas pelo simulador seriam muito difíceis de se obter mesmo usando um hardware real. Dentre as informações que o simulador gera, tem-se dados estatísticos de ciclos executados, instruções executadas, CPI, taxas de single e dual issue, estatísticas de stalls, uso de registradores, histograma de instruções, taxa de branch misprediction, e outros. As informações sobre branch misprediction, por exemplo são extremamente valiosas já que não há suporte em hardware na SPU para branch prediction e um mispredict custa 18 ciclos de execução. O estudo dos branch misprediction permite que diminua esta taxa. Dentre as técnicas utilizadas para diminuição de branch misprediction, tem-se: escrever o caminho mais freqüente como código inline, calcular os dois caminhos do branch e só depois escolher o resultado correto, loop unroll e instruções de hint. Além disso, o simulador possibilita o acesso aos dados de execução do processador (conteúdo da memória, registradores PPU e SPU, LS, etc.) durante a execução dos programas. 2. SPU Dynamic Profiling com IBM Cell BE full-system Simulator Como explicado em [12], para que a funcionalidade de profile dinâmico do simulador seja ligada, são necessárias duas coisas. Primeiramente deve se configurar as SPEs para rodar no modo pipeline através do botão SPU Modes da interface gráfica do simulador. Este modo liga no simulador o componente de coleta de informações e simulação temporal de diversos componentes da micro-arquitetura do SPU como in-order issue, ausência de register renaming, branch hints controlados por software sem suporte algum no hardware, regras de arbitragem do Local Store e outras. Por padrão este modo pipeline está desligado para que a simulação seja apenas funcional e não temporal, o que a torna mais rápida. Além disso, é necessário incluir algumas instruções especiais no código SPU sendo executado no simulador para que o mesmo possa identificar onde ele deve ligar/desligar a coleta de informações de performance, já que tal processo deixa a simulação bem mais lenta. Estas instruções estão disponíveis através da interface profile.h, que fornece os procedimentos prof_clear(), prof_start() e prof_stop(). Estes procedimentos se traduzem em instruções assembly que não alteram o estado do sistema, como, por exemplo, and $0,$0,$0. Quando o simulador com o modo pipeline das SPUs ligado executa uma instrução destas, ele identifica que deve limpar, ligar ou desligar a coleta de dados de performance.
  • 39. Os dados coletados durante a análise de performance podem ser visualizados de duas formas: pela interface de linha de comando do simulador ou diretamente na interface gráfica do simulador. Neste mini-curso, como o nosso foco é na facilidade de uso das ferramentas para a plataforma Cell BE daremos ênfase apenas no uso da interface gráfica do simulador mostrada na figura 21. Figura 21: Interface gráfica do simulador As estatísticas de execução do código SPU obtidas pela coleta de dados de performance podem ser acessadas expandindo-se a árvore de uma SPE do lado direito da janela gráfica do simulador e acessando o nó SPU Stats. O resultado desta ação é mostrado na figura 22.
  • 40. Figura 22: Estatísticas geradas pela análise de performance do simulador. Dentre os dados possíveis de serem analisados pelos dados estatísticos gerados pelo simulador encontram-se: número de ciclos da SPU em que foram executados, duas instruções ou uma instrução, número de ciclos em stall, distribuição estatística dos motivos geradores de stall, número de instruções de branch e quantos branches foram perdidos, número de branch hints que acertaram e muitas outras. O simulador ainda permite, através da interface gráfica, o acesso a informações como o histograma de instruções executadas pelo programa SPU, gráficos estatísticos sobre performance e uso do Local Store e outros. Ele também permite que se configure um breakpoint de execução através da análise de endereços de memória: quando um determinado endereço de memória for lido ou escrito a execução do programa é parada e o programador pode, assim, saber exatamente o que estava acontecendo quando tal região de memória estava sendo acessada, facilitando o trabalho de debug de aplicações complexas com diversas threads interagindo entre si. Gráficos estatísticos da execução no SPE podem ser acessados através do botão SPE Visualization da interface gráfica do simulador. Talvez a maior dificuldade que se tenha ao analisar os dados de performance gerados pelo simulador seja achar em qual SPE simulada a thread SPE criada foi executada. Por padrão, na arquitetura Cell BE não é possível indicar em qual núcleo SPE uma determinada thread deve ser executada: a alocação da thread em um núcleo SPE é coordenada pelo barramento interno do
  • 41. processador e nem mesmo o sistema operacional possui este controle. No caso do simulador uma pequena regra costuma funcionar: a primeira thread SPE alocada para rodar ocupará o SPE7, a segunda ocupará o SPE6 e assim por diante. Quando se chegar no SPE0 volta-se ao SPE7 e assim sucessivamente. Note que esta é apenas uma dica geral e não há garantia nenhuma de que a ordem de alocação das SPEs físicas seja esta sempre. 3. Outras ferramentas de análise de performance Como vimos no caso do simulador, as ferramentas de análise de performance são essenciais para se tirar um bom proveito de todo o poder de processamento que a plataforma Cell BE pode entregar. Por isso, além do simulador, outras várias ferramentas de análise de performance estão disponíveis para esta plataforma. Estas ferramentas muitas vezes são focadas no SPE, já que é a partir da vetorização e paralelização de código nele é que se constrói o ganho expressivo de performance em aplicações rodando em processadores Cell. Destacam-se mais duas ferramentas de análise de performance além do simulador: SPU Timing, que faz análise estática do código assembly SPU, mostrando o código e os estados de pipeline do processador; e FDPR-Pro, que é uma ferramenta de otimização que modifica os executáveis do programa através da análise de sua execução após o processo de link final. 3.1. SPU Timing O SPU Timing é uma ferramenta que faz análise estática do código assembly SPU. Ele não leva em conta instruction fetch stalls, Local Store contention e branching, assumindo execução linear do código. A primeira vista este tipo de análise pode parecer de pouca utilidade, mas temos que lembrar que a SPU é um processador no qual não há chaveamento de contexto nem várias threads concorrendo por recursos. Ou seja, um mesmo programa na SPU sempre executará exatamente da mesma maneira, gastando o mesmo número de ciclos de clock, para a mesma entrada de dados todas as vezes que for executado. Sob este aspecto a análise estática passa a ser valiosa para a análise da performance obtida no processamento e para verificação dos pontos onde é possível ainda melhorar o desempenho. Com o SPU Timing é possível visualizar facilmente os pontos do processamento onde estão ocorrendo stalls de pipeline ou pouco aproveitamento do dual issue das SPUs. Sabendo onde estes problemas ocorrem, o programador pode verificar se é possível modificar alguma coisa no código-fonte original de forma a diminuir estes efeitos indesejados.
  • 42. 3.2. FDPR-Pro O Feedback Directed Program Restructuring (FDPR-Pro) é uma ferramenta de tuning de performance que tenta reduzir o tempo de execução e o uso de memória das aplicações. Ele trabalha com o código executável (post link) e é capaz de alterar o código executável diretamente, sem necessidade de acesso ao código-fonte. Para isso ele é executado em duas fases: instrumentation e optimization. Após criar a versão instrumentada do código, ele coleta informações sobre o comportamento do programa em cima de uma carga de trabalho típica fornecida pelo programador. Em seguida, ele cria uma nova versão do programa otimizada para a carga de trabalho típica que, em geral, é mais rápida e usa menos memória que a versão original.
  • 43. Capítulo 5 Trabalhos Relacionados 1.Introdução Este capítulo final do nosso minicurso tem por objetivo de relacionar as linguagens de programação que estão em desenvolvimento para plataforma Cell BE, os trabalhos de pesquisas em Universidades e ferramentas comerciais para prototipagem rápida no Cell. Podemos relacionar as seguintes ferramentas de software e tecnologias: 1. IBM Octopiler [19]. 2. Código e Particionamento de dados para memória local do processador Cell BE [20] 3. Compilador CellSs para OpenMP em memória privada [21, 22, 23]. 4. Glimpses e Cellule. Na tabela 1 a seguir, relacionamos os trabalhos mais importantes desenvolvidos na plataforma Cell BE: Computação Científica Softwares Comerciais Desenvolvimento de Algoritmos Numéricos Paralelos de Alta Performance para o Processador Cell [24] Computação Científica para Cluster de Playstation 3 [25]. Plataforma de Desenvolvimento RapidMind e Programação Paralela de Dados [26] Biblioteca de Processamento de Sinais pelo MIT Multicore Framework (MFC) para Cell BE pela Mercury Systems [27] Mercado Financeiro [29] Aplicações Aeroespaciais e Geociências Tabela 1: Comparação entre Softwares de Computação Científica e Comerciais
  • 44. Atualmente, várias linguagens de programação são portadas para novo paradigma de programação multicore do Cell BE. Descrevemos algumas delas na tabela 2: Linguagens de Programação Universidade / Empresa Charm++ [28] University of Illinois – Urbana Champgne (UIUC) Programação Sintética com Phyton University of Indiana Programação OpenMP University Polithecnical of Barcelona (UPC) Programação para Playstation – Desenvolvimento para Jogos Programação Sequoia no PS3 [29] Stanford University Tabela 02: Linguagens de Programação no Cell O Grupo de Computação Pervasiva e Processamento de Alto Desempenho (PAD), em especial, o aluno de doutorado Roberto Kenji Hiramtsu, da Universidade de São Paulo desenvolveu um software para detecção de faces, chamado CELL FaceDetect [30], que utiliza a biblioteca OpenCV, otimizado para Cell BE. Este software ganhou em quarto lugar na região das Américas, o concurso da IBM - “Cell Contest'07 Beyond on Gaming” [31]. Para o trabalho de Tese, está sendo propostos vários módulos de reconhecimento de faces para um sistema de vídeo segurança.
  • 45. Referências [1] J. M. Eastep. Msc Thesis, Massachusetts Institute of Technology, March 2007. [2] M. Gschwind, H. P. Hosftee et al, Y. Watanabe and T. Yamazaki. Paper in Hot Chips 17. In (Synergistic Processing in Cell's Multicore Architecture), Stanford University, pages 10- 24, 2006. [3] H. P. Hosftee. Paper IEEE in HPCA-11, “Power Efficient Processor Architecture and The Cell Processor”, pp. 258-262, February 2005. [4] J. Easton, I. Meents, O. Stephan, H. Zisgen, S. Kato. IBM Whitepaper, “Porting Financial Markets Applications to the Cell Broadband Engine Architecture”, June 2007. [5] F. Pham et al. Paper in ISSCC Dig. Tech, “The Design and Implementation of a First- Generation CELL Processor,” Paper 10.2, pp. 184-185, Feb., 2005. [6] B. Flachs et al. Paper in ISSCC Dig. Tech, “A Streaming Processing Unit for a CELL Processor”, Paper 7.4, pp. 134-135, Feb., 2005. [7] Duc Vianney. “Cell Software Solutions Models Programming”, Game Developers Conference 2006. Presentation. Available on: www.power.org/resources/devcorner/cellcorner/DucVianney_GDC- CellSoftwareSolutionsProgrammingModel.pdf [8] H. P. Hosftee. White Paper, “Introduction to the Cell Broadband Engine”, IBM Corporation, 31/10/2005. [9] J. A. Kahle, M. N. Day, H. P. Hosftee, et al. IBM Journal of Research and Development, “Introduction to the Cell Multiprocessor”, volume 49, Number 4/5, 2005. [10] Barcelona Supercomputing Center Site. Disponível em: http://www.bsc.es/plantillaG.php?cat_id=179 [11] Software Development Kit for Multicore Acceleration Version 3.0 Programming Tutorial Draft disponível em /opt/cell/sdk/docs/programming através da instalação do pacote cell-documentation. [12] Lewin Edwards. An introduction to compiling for the Cell Broadband Engine architecture, Part 1: “A birds-eye View”. Disponível em: http://www.ibm.com/developerworks/edu/pa-dw-pa- cbecompile1-i.html?S_TACT=105AGX16&S_CMP=LP [13] Alexandre E. Eichenberger, Kathryn O'Brien, Kevin K. O'Brien, Peng Wu, Tong Chen, Peter H. Oden, Daniel A. Prener, Janice C. Shepherd, Byoungro So, Zehra Sura, Amy Wang, Tao Zhang, Peng Zhao, and Michael Gschwind. “Optimizing Compiler for the CELL Processor”, PACT05, Saint Louis, Missouri. Disponível em: http://pact05.ce.ucsc.edu/ [14] Compiler Technology for Scalable Architectures. Disponível em: http://domino.research.ibm.com/comm/research_projects.nsf/pages/cellcompiler.index.html [15] Software Development Kit for Multicore Acceleration Version 3, “Installation Guide Version 3.0”, Setembro, 2007. Disponivel no AlphaWorks: [16] Portal CellBR Website. Disponivel em: http://www.pad.lsi.usp.br/cell. Acessado em: 25 de setembro de 2007. [17] Eclipse.org. Disponível em: http://www.eclipse.org. Acessado em: 25 de setembro de 2007.[18] IBM Book. “SPE Runtime Management Library Version 2.2”. Disponível em: http://www- 01.ibm.com/chips/techlib/techlib.nsf/techdocs/4818FA471C13A1BC872572AB006C4139. Acessado em: 25 de setembro de 2007.
  • 46. [19] IBM Octopiler Site. Disponível em: http://domino.research.ibm.com/comm/research_projects.nsf/pages/cellcompiler.index.html. Acesso em 25 de setembro de 2007. [20] Obrien. Apresentação no Sony/Toshiba/IBM Workshop on Software and Applications for Cell/BE processor. Georgia Tech, June 18-19, 2007. Disponível em: http://sti.cc.gatech.edu/program.html. Acessado em: 25 de setembro de 2007. [21] J.M. Perez, P. Bellens, R.M. Badia, and J. Labarta. Artigo publicado no IBM Journal of Research and Development. “CellSs: Making it easier to program the Cell Broadband Engine processor”, Cell Broadband Engine Technology and Systems, Volume 51, Number 5, 2007. [22] P. Bellens, J. Perez, R. Badia, J. Labarta. Artigo publicado no SC'07. “CellSs: a programming model for the cell BE architecture”, Proceedings of the 2006 ACM/IEEE Conference on Supercomputing, number 86, 2006. [23] Cell Superscalar Site. Barcelona Supercomputing Center. Disponível em: http://www.bsc.es/plantillaG.php?cat_id=179. Acessado em: 25 de setembro de 2007. [24] A. Buttari, J. Dongarra, and J. Kurzak. Relatório Técnico. “Limitations of the PlayStation 3 for High Performance Cluster Computing”, UT-CS-07-597, May 2007. [25] Buttari, A., Luszczek, P., Kurzak, J., Dongarra, J., Bosilca, G. Relatório Técnico. “SCOP3: A Rough Guide to Scientific Computing On the PlayStation 3”, University of Tennessee Computer Science Dept. Technical Report, UT-CS-07-595, April 17, 2007. [26] RapidMind Website. Disponível em: http://www.rapidmind.net/case-studies.php. Acessado em: 25 de setembro de 2007. [27] Mercury System Website. Disponível em: http://www.mc.com/microsites/cell/. Acessado em: 25 de setembro de 2007. [28] D. Kunzman, G. Zheng, E. Bohm, L. V. Kale. Poster. “Charm++ Simplifies Programming for the Cell Processor”. Disponível em: http://charm.cs.uiuc.edu/posters/. Acessado em: 25 de setembro de 2007. [29] Houston M. Apresentação no CscADS Workshop. “Sequoia”. Stanford University, July 9th , 2007. Disponível em: http://cscads.rice.edu/workshops/july2007/autotune-slides- 07/Houston.pdf [30] Projeto CELL FaceDetect Website. Disponível em: http://www.pad.lsi.usp.br/cell/index.php?option=com_content&task=view&id=21&Itemid=0. Acessado em: 25 de setembro de 2007. [31] Concurso Cell Contest'07 Website. Disponível em: http://www- 304.ibm.com/jct09002c/university/students/contests/cell/index.html