Content uploaded by Henrique Cota Freitas
Author content
All content in this area was uploaded by Henrique Cota Freitas
Content may be subject to copyright.
Capítulo
3
Ensinodearquiteturasdeprocessadoresmany-core
e memórias cache utilizando o simulador Simics
Marco Antonio Zanata Alves (UFRGS - mazalves@inf.ufrgs.br)
Henrique Cota de Freitas (PUC Minas - cota@pucminas.br)
Philippe Olivier Alexandre Navaux (UFRGS - navaux@inf.ufrgs.br)
Abstract
Concerning the rise of new generations of many-core processors with the possibility of
tens or hundreds of processor cores for general purpose, the teaching of processor ar-
chitecture becomes a great challenge, especially considering the rapid development of
the area. In this context, there is also several design alternatives with new concepts and
techniques that increase the exploration space for students in disciplines related to the
computer architectures. This chapter presents an approach of using a full system simu-
lation environment, called Simics in the classroom, focusing on design, simulation and
evaluation of architectures of many-core processors. To support this approach, we used
our experience of evaluating of shared cache memory on many-core processors, which
will be presented throughout this chapter, together with results obtained by students in
the classroom.
Resumo
Com o surgimento das novas gerações de processadores many-core com possibilidade
de dezenas ou centenas de núcleos de processamento de propósito geral, o ensino de ar-
quitetura de processadores se torna um grande desafio, principalmente considerando a
rápida evolução da área. Neste contexto, surgem também várias alternativas de projeto
com novos conceitos e técnicas que aumentam o espaço de exploração dos alunos nas
disciplinas relacionadas à arquitetura de computadores. Este capítulo apresenta uma
abordagem de uso de um ambiente de simulação de sistema completo chamado Simics
em sala de aula, focando no projeto, simulação e avaliação das arquiteturas de proces-
sadores many-core. Para dar suporte a esta abordagem, foram utilizadas as experiências
de avaliação de memórias cache compartilhadas em processadores many-core, a qual
será apresentada ao longo deste capítulo, juntamente com resultados obtidos por alunos
em sala de aula.
Livro "Arquitetura de Computadores: Educação, Ensino e Aprendizado", 1ed.Porto Alegre: Sociedade Brasileira de Computação, 2012, v. 1, p. 74-110.
ISBN: 9788576692638
3.1. Introdução
A busca por desempenho computacional tem aumentado ao longo das décadas, através da
exploração de técnicas como pipeline, superescalaridade e multithreading. Estas técnicas
aumentam o paralelismo de execução das aplicações e assim reduzem o tempo de exe-
cução e obtenção de resultados. Com base nestas técnicas, o projeto de uma arquitetura
pode focar o paralelismo no nível de instrução ou threads. Arquiteturas superescalares
têm como característica principal a execução paralela de instruções e exploram o au-
mento da freqüência de operação para atingir altas taxas de desempenho. O suporte a
múltiplas threads [1] [2] é uma alternativa de exploração de paralelismo não mais no
nível de instruções, mas no nível de fluxo de instruções (threads). A principal diferença
entre arquiteturas superescalares e multithreading pode ser explicada pelas cargas de tra-
balho. Cargas com alto paralelismo no nível de instruções podem ser melhores suportadas
por arquiteturas superescalares, enquanto cargas com alto paralelismo no nível de threads
são melhores suportadas por arquiteturas multithreading.
As abordagens single-threading e superescalares tradicionais vêm dando lugar a
abordagens diferentes a fim de aumentaraindamais o desempenho e reduzir o consumo de
potência. O projeto de processadores com técnicas multithreading e múltiplos núcleos de
processamento mais simples (arquiteturas com pouco suporte de paralelismo no nível de
instrução) vem sendo consolidado como uma alternativa para o aumento do desempenho
computacional. Para a nova geração de processadores com arquiteturas many-core, a
quantidade elevada de núcleos demanda um novo tipo de projeto baseado em um sistema
heterogêneo com diversos núcleos diferentes, memórias cache, redes de interconexões,
protocolos de coerência adequados, a fim de obter um alto desempenho no sistema final.
Neste contexto de arquiteturas many-core, fica clara a necessidade do ensino de
diversos novos conceitos aos alunos nas disciplinas de arquiteturas de computadores. En-
tretanto, essa tarefa de ensino pode ser um pouco abstrata, caso os alunos não consigam
aplicar e trabalhar, mesmo que em ambiente simulado, os conceitos aprendidos em sala
de aula.
Portanto, o objetivo principal desse capítulo é apresentar uma experiência de en-
sino e avaliação de processadores many-core através de um ambiente de simulação que
propicie aos alunos e professores a exploração de diferentes configurações de arquiteturas
e organização. Para isso, será apresentado de forma descritiva como utilizar um ambiente
de simulação completo em sala de aula, além das possíveis métricas de avaliação de de-
sempenho que podem ser aplicadas. A meta final é difundir as experiências relacionadas
ao uso de um simulador completo em sala de aula tendo como foco uma melhor formação
dos alunos para próxima geração de processadores many-core. Para isso, os métodos
apresentados foram definidos a partir do trabalho de pesquisa que visava a avaliação de
memórias cache compartilhadas em diferentes arquiteturas de processadores many-core,
e dos resultados de avaliações dos trabalhos executados pelos alunos.
Este capítulo é organizado da seguinte forma. A Seção 3.2 apresenta uma breve
introdução sobre arquiteturas de processadores multi-core e many-core. A Seção 3.3 trará
conceitos relacionados as arquiteturas de memória cache compartilhadas, que será o ob-
jeto de estudo desse capítulo. A Seção 3.4 irá apresentar um método para avaliação de
memória cache compartilhadas. A Seção 3.5 mostra a importância de ambientes de simu-
Livro "Arquitetura de Computadores: Educação, Ensino e Aprendizado", 1ed.Porto Alegre: Sociedade Brasileira de Computação, 2012, v. 1, p. 74-110.
ISBN: 9788576692638
lação de sistemas completos. A Seção 3.6 foca principalmente na apresentação do Simics.
A Seção 3.7 apresenta alguns estudos de caso. Por fim, a Seção 3.8 trará as principais con-
clusões relacionadas às experiências obtidas.
3.2. Arquiteturas de Processadores Multi-Core e Many-Core
O estudo das atuais arquiteturas de processadores multi-core disponíveis no mercado é de
grande importância para avaliar a direção traçada atualmente pelas indústrias de proces-
sadores. Um dos pontos principais para o desempenho do processador nas arquiteturas
multi-core está na organização da memória cache. As pesquisas em desenvolvimento e
os processadores comerciais apontam diferenças na influência do compartilhamento e dos
níveis de memórias cache escolhidas. Nesta seção são abordadas as principais caracterís-
ticas dos projetos deprocessadorescom uma visão evolutiva e dos problemas relacionados
na escolha de uma característica específica.
Vários projetos de arquiteturas de processadores vêm adotando ao longo de dé-
cadas diversas técnicas tradicionais [3] [4] [5] [2] [1] como pipeline, superescalaridade e
multithreading para explorar o paralelismo de execução das aplicações e assim melhorar
o desempenho de computadores de propósito geral.
Em um pipeline superescalar [4], além do processamento de instruções ser divi-
dido em estágios, é feita uma completa sobreposição das instruções, utilizando para isso,
o aumento do número de unidades funcionais e técnicas para solucionar falsas dependên-
cias entre as instruções, dentre outras. Desta forma, os processadores superescalares são
capazes de aumentar consideravelmente o desempenho na execução de cargas de trabalho
com alto paralelismo no nível de instruções.
O suporte a múltiplas threads [2] [1] é uma alternativa de exploração de par-
alelismo não mais no nível de instruções, mas no nível de fluxo de instruções (threads).
Isso significa um aumento na vazão de threads, podendo mais de uma thread ser execu-
tada ao mesmo tempo, ao contrário da superescalaridade onde a vazão é de instruções
de uma única thread. Diversas são as técnicas para exploração do paralelismo no nível
de threads, sendo que a mais conhecida é a SMT (Simultaneous Multithreading) que é
suportada por uma arquitetura superescalar.
Ao longo de décadas, as técnicas de aumento de profundidade do pipeline aliado
ao aumento da freqüência de trabalho do processador (ciclo de relógio) foram utilizadas
a fim de obter o máximo desempenho a cada nova geração de processador. O custo para
esse ganho de desempenho foi o aumento da complexidade da unidade de controle dos
processadores, assim como o aumento no consumo de potência e temperatura do sistema
computacional. Entretanto, esta forma tradicional de aumento de desempenho começou a
apresentar problemas físicos, relacionados com o alto grau de integração dos componentes
como o atraso do fio, consumo de potência estática, entre outros. Assim, essa complexa
abordagem de extração de paralelismo vem dando lugar a uma abordagem diferente. A
fim de aumentar ainda mais o desempenho, e ainda, algumas vezes diminuir a potência
dissipada, o uso de processadores com múltiplos núcleos (CMPs - Chip Multi-Processors)
[6] vem sendo consolidada [7] [8] [9] [10] como uma boa abordagem para o aumento do
desempenho de computação.
Livro "Arquitetura de Computadores: Educação, Ensino e Aprendizado", 1ed.Porto Alegre: Sociedade Brasileira de Computação, 2012, v. 1, p. 74-110.
ISBN: 9788576692638
Ainda com a técnica de múltiplos núcleos no mesmo chip, nada impede que sejam
utilizadas superescalaridade e SMT em cada núcleo, mas nesses casos pode haver um
aumento considerável na área do CMP em função da duplicação de registradores além de
outros componentes. Em função desta nova abordagem de projeto, os processadores com
múltiplos núcleos e que suportam múltiplas threads também são conhecidos como CMT
ou Chip Multithreading [11] [12].
3.2.1. Processadores Multithreading
Nos projetos atuais de processadores, um dos grandes objetivos é a extração máxima do
desempenho. Uma das formas está na exploração do paralelismo, seja na execução das
instruções ou nos fluxos de instruções. Nesse contexto, podemos considerar que um fluxo
de instruções é uma thread e que uma thread é um processo, ou parte de um programa em
execução. Se um processador suporta a execução de múltiplas threads [13] [14] [15] [16],
significa que esse processador é capaz de executar fluxos de instruções diferentes. Nesse
caso, cada uma destas threads, ou fluxo de instruções, inicia em endereços diferentes de
memória.
O suporte à multithreading possui duas abordagens [1] [2]: Implicit Multithread-
ing e Explicit Multithreading:
• Implicit Multithreading: Exploração do paralelismo existente em programas se-
qüenciais através de especulação no nível de thread. Nessa abordagem, um pro-
cessador gera múltiplas threads especulativas de um único programa seqüencial,
dinamicamente, ou estaticamente com ajuda do compilador, e executa todas con-
correntemente.
• Explicit Multithreading: Exploração do paralelismo existente entre programas de
origens diferentes. As threads geradas a partir de cada um desses programas podem
ser executadas em um mesmo pipeline.
Nos dois casos, cada uma das threads possui um banco de registradores e conta-
dores de programa específicos, representando cada um dos múltiplos contextos em ativi-
dade no processador. A diferença está no uso de execução especulativa de threads de
um mesmo programa seqüencial na abordagem implicit multithreading ou na execução
de threads independentes e de programas distintos na abordagem explicit multithreading.
Um único núcleo de processamento (escalar ou superescalar) pode suportar múlti-
plas threads. Pequenas modificações na organização interna do núcleo são responsáveis
por permitir a execução simultânea ou chaveada das threads.
Ainda em se tratando de multithreading, podemos ter diversos tipos de exploração
de paralelismo no nível de threads, como SMT (Simultaneous Multithreading), IMT (In-
terleaved Multithreading) e BMT (Block Multithreading).
• Simultaneous Multithreading: Esse tipo avançado de multithreading se aplica a pro-
cessadores superescalares. Um processador superescalar simples busca instruções
da mesma thread a cada ciclo do processador. Em um processador SMT, o proces-
sador pode buscar instruções de várias threads a cada ciclo do processador. Esse
Livro "Arquitetura de Computadores: Educação, Ensino e Aprendizado", 1ed.Porto Alegre: Sociedade Brasileira de Computação, 2012, v. 1, p. 74-110.
ISBN: 9788576692638
tipo de multithreading se prevalece do fato de que, para uma única thread, o número
de instruções paralelas a serem buscadas e executadas é limitado. Assim, buscando
instruções de múltiplas threads, o processador tenta reduzir o número de unidades
funcionais sem uso a cada ciclo de relógio.
• Interleaved Multithreading: A execução de cada thread é alternada em cada ciclo
de relógio do processador. Esse modo de trabalho visa remover todas paradas por
dependência de dados de um pipeline. Uma vez que uma thread é relativamente
independente das outras threads, existe menos chance de uma instrução precisar es-
perar por um dado de uma instrução executada anteriormente, uma vez que existirá
instruções de outras threads intercaladas no pipeline.
• Block Multithreading: Cada thread é executada até que seja bloqueada por um
evento que normalmente cria um longo período de espera. Tal evento pode ser uma
falta de dados na memória cache criando assim uma latência para acesso aos dados.
Dessa maneira, ao invés de esperar o evento de alta latência, o processador deverá
trocar a execução para outra thread que esteja pronta para execução. A thread que
ocasionou o evento de alta latência só receberá status de pronta para execução assim
que sair do estado de espera. Esse modelo de multithreading visa esconder as altas
latências de acesso à memória, mascarando essas latências com a execução de outro
fluxo de instruções.
3.2.2. Processadores Multi-Core
Pesquisas sobre as melhores alternativas de projeto de arquiteturas de processadores têm
usado basicamente o estudo de cargas de trabalho para entender melhor o comportamento
do processador.
Um dos primeiros estudos que identificou o potencial do uso de chip multiproces-
sor foi proposto em [6], onde foi apresentado um estudo onde dois tipos de arquiteturas
foram expostos a um mesmo tipo de carga de trabalho. O estudo procurou definir qual
o melhor tipo de arquitetura para cargas onde havia um baixo ou grande paralelismo
no nível de thread. A Figura 3.1 [6] apresenta os dois tipos de arquiteturas que foram
comparadas, uma arquitetura superescalar com execução de seis instruções simultâneas
e uma arquitetura com múltiplos núcleos de processamento suportando duas instruções
simultâneas por núcleo de processamento.
Para garantir apenas a influência da carga de trabalho submetida, os dois projetos
possuíam as mesmas latências de acessos à memória principal, mesmo tempo de acesso à
memória cache e a mesma ocupação de área. Então, as mesmas cargas de trabalho com
características de operações de números inteiros, ponto flutuante, e de multiprogramação
foram aplicadas aos dois projetos.
Os resultados demonstraram que para cargas de trabalho onde os fluxos de in-
struções das aplicações não são paralelizáveis, o ganho é favorável ao processador su-
perescalar em 30%. Nesse caso existe uma exploração melhor do paralelismo no nível de
instrução. Para aplicações onde existe um baixo paralelismo de threads, o ganho ainda
é favorável à arquitetura superescalar, mas no máximo de 10%. No entanto, onde há um
Livro "Arquitetura de Computadores: Educação, Ensino e Aprendizado", 1ed.Porto Alegre: Sociedade Brasileira de Computação, 2012, v. 1, p. 74-110.
ISBN: 9788576692638
Figura 3.1. Comparativo de processadores [6], (a) Processador superescalar, (b)
Processador multi-core.
grande paralelismo no nível de thread, o ganho passa a ser da arquitetura CMP variando
de 50% a 100% em relação ao superescalar.
As cargas de trabalho com grandes níveis de paralelismo em thread executam
aplicações independentes com processos independentes. Aplicações de visualização e
multimídia, processamento de transações e aplicações científicas de ponto flutuante são
exemplos destas cargas de trabalho. Esta pesquisa serviu como base para o processador
Hydra CMP [17], e também gerou resultados para o processador UltraSparc-T1 [9].
Atualmente, a grande maioria dos processadores de propósito geral são exem-
plos de arquiteturas com núcleos homogêneos (iguais) e para um mesmo propósito de
funcionamento (aplicações gerais no caso do GPP - General-Purpose Processor). No
entanto, projetos de processadores multi-core para aplicações em sistemas embarcados,
freqüentemente possuem núcleos heterogêneos [18] [10]. Nesse caso, cada núcleo, ou
conjunto de núcleos, é responsável por processamentos específicos e distintos dos de-
mais. Uma classe de processadores que representa adequadamente as arquiteturas com
núcleos heterogêneos são os processadores conhecidos como MPSoCs (Multi-Processor
System-on-Chip) [19]. Estes processadores podem apresentar mais de um processador
GPP (General-Purpose Processor) ou ASIP (Application Specific Instruction Set Archi-
tecture) interno ao chip, porém cada um desses possui características diferentes, onde um
determinado núcleo pode se adequar melhor a um conjunto de aplicações enquanto outro
núcleo se encaixa melhor a um segundo conjunto de aplicações.
A Figura 3.2, estendida de [2] apresenta uma comparação entre um superescalar
de quatro vias 3.2(a), um processador SMT (Simultaneous Multithreading) 3.2(b), um
processador IMT (Interleaved Multithreading) 3.2(c), um processador BMT (Block Mul-
tithreading) 3.2(d), sendo todos CMT superescalares de quatro vias, e por fim, um pro-
cessador multi-core onde cada um dos dois núcleos é um superescalar de duas vias 3.2(e).
Fora o processador superescalar simples, todos os processadores são CMTs que
suportam de duas (CMP) até quatro threads (SMT, IMT e BMT) simultâneas. No pro-
cessador superescalar simples apenas uma thread está ativa por vez (A), assim apenas
instruções de uma thread são executadas até que haja uma troca de contexto. Para o
processador SMT, quatro threads ficam ativas (A, B, C e D), além disso, instruções das
Livro "Arquitetura de Computadores: Educação, Ensino e Aprendizado", 1ed.Porto Alegre: Sociedade Brasileira de Computação, 2012, v. 1, p. 74-110.
ISBN: 9788576692638
(a) Superescalar (b) SMT (c) IMT (d) BMT (e) CMP
Figura 3.2. Comparativo entre processadores superescalar, processadores mul-
tithreading e multi-core. Na vertical está ilustrado a linha do tempo de execução,
na horizontal encontram-se as vias de execução de cada processador. Pode-se
ver ainda, as vias de execução ocupadas com os fluxos de instrução (A, B, C e
D).
quatro threads podem ser executadas em um mesmo ciclo de máquina aproveitando to-
das as unidades funcionais. Já no caso do IMT e BMT, apenas instruções de uma thread
são executadas por ciclo, onde a troca entre threads ativas acontece a cada ciclo no caso
do IMT e para o BMT a troca ocorre ao executar um evento de alta latência. No caso
do multi-core ou CMP (Chip Multiprocessor) cada núcleo recebe uma única thread, mas
duas instruções de cada thread podem ser executadas ao mesmo tempo. Assim, para que
um núcleo passe a operar sobre outra thread, deve haver uma troca de contexto, o que é
um evento de mais alta latência que a troca entre threads ativas.
3.3. Arquiteturas de Memórias Cache Compartilhadas
Devido ao aumento do número de núcleos de processamento dentro do processador, novos
modos de organização da hierarquia de memória estão sendo estudados. As memórias
cachepara esses processadores podem ser privadas ou compartilhadas conforme apresenta
a Figura 3.3.
Em um modelo de organização de memória cache privada cada processador possui
sua própria hierarquia de memória cache totalmente isolada, como apresentado na Figura
3.3(a), somente interconectada aos demais núcleos por meio da memória principal.
No modelo de memória cache compartilhada, ilustrado na Figura 3.3(b), existe
pelo menos um nível na hierarquia de memórias cache compartilhada entre dois ou mais
núcleos de processamento. No caso ilustrado, a memória cache está compartilhada a cada
dois núcleos de processamento.
A utilização de modelos de memórias cache privadas ou compartilhadas influencia
no projeto do sistema, uma vez que questões sobre a implementação do protocolo de
coerência e consistência entre as memórias, além da quantidade de portas de entrada e
saída necessárias na memória cache, largura de banda de interconexão e área do projeto,
são afetados pelo modelo de organização de memória privada ou compartilhada.
Livro "Arquitetura de Computadores: Educação, Ensino e Aprendizado", 1ed.Porto Alegre: Sociedade Brasileira de Computação, 2012, v. 1, p. 74-110.
ISBN: 9788576692638
(a) Memórias cache privadas. (b) Memórias cache compartilhada.
Figura 3.3. Diagrama representando organizações de memórias cache, apresen-
tando memórias cache privadas 3.3(a) e compartilhadas 3.3(b).
O desempenho do sistema também pode ser influenciado pelo modo de compartil-
hamento de memória cache adotado, uma vez que o compartilhamento poderá favorecer o
desempenho reduzindo o número de faltas quando os processadores que compartilham es-
tiverem trabalhando no mesmo conjunto de dados. Por outro lado, a quantidade de faltas
de dados relacionadas ao conflito de endereços e capacidade pode aumentar se os dados
em uso não forem os mesmos nos processadores que compartilham a memória cache.
Juntamente com esse modelo de memória compartilhada entre vários núcleos, al-
gumas preocupações foram inseridas durante o projeto de uma memória cache para os
novos processadores com múltiplos núcleos de processamento. Algumas das questões
que ganharam mais força nesse novo modelo de memória foram o controle de coerên-
cia entre memórias cache, estrutura de interconexão, portas de entrada e saída para as
memórias, entre outras.
3.3.1. Coerência e Consistência da Memória Cache
Ao tratar de coerência de dados em memórias cache, estamos envolvendo dois aspectos
importantes. O primeiro diz respeito à coerência, que define quais valores devem ser
retornados durante a leitura. O segundo aspecto é a consistência, que determina quando
um valor gravado será retornado por uma leitura.
Assim, de acordo com [3], um sistema de memória é considerado consistente se:
• A ordem do programa for preservada. Uma leitura pelo processador P
i
em uma
posição X após uma gravação por P
j
em X, sem a ocorrência de gravações em
X por outro processador entre a gravação e leitura por P
i
, sempre retorna o valor
gravado por P
j
.
• Existe uma visão coerente da memória. Uma dada leitura da posição X pelo proces-
sador P
i
após uma gravação em X por P
j
retorna o valor gravado por P
j
se a leitura
e a gravação estiverem bastante separadas no tempo e não ocorrer nenhuma outra
gravação em X entre os dois acessos.
• Gravações na mesma posição são serializadas. Duas gravações na mesma posição
Livro "Arquitetura de Computadores: Educação, Ensino e Aprendizado", 1ed.Porto Alegre: Sociedade Brasileira de Computação, 2012, v. 1, p. 74-110.
ISBN: 9788576692638
por dois processadores quaisquer serão vistas na mesma ordem por todos os pro-
cessadores.
Mesmo que o modelo ideal seja que, após um processador gravar um dado na
memória, esse seja atualizado instantaneamente em todas as suas cópias, esse modelo
talvez seja impossível de ser implementado. A noção de quando um dado gravado será
visível para leituras é tratada pela consistência da memória.
Assim, podemos notar que a noção de coerência e consistência são complementares,
pois enquanto a coerência define o comportamento de leituras e gravações em uma mesma
posição, a consistência define o comportamento de leituras e gravações em relação a aces-
sos a outras posições de memória.
3.3.2. Protocolos de Coerência
Em um multiprocessador coerente, as memórias cache fornecem tanto a migração quanto
a replicação de dados compartilhados. Dessa forma, mesmo que existam diversos pro-
cessadores trabalhando sobre os mesmos dados, cada processador deverá agir sem se
preocupar com a existência de outras cópias dos mesmos dados em outros processadores.
As memórias cache coerentes proporcionam migração, pois qualquer dado pode
ser movido para a cache e operado de forma transparente. Essas memórias cache também
proporcionam replicação, pois diversas memórias cache podem conter cópias de um dado
referentes ao mesmo endereço.
Dessa forma, é importante ressaltar que, de acordo com [20], o problema de
coerência de dados apresenta-se apenas em arquiteturas multiprocessadas que associam
memórias cache a cada um dos processadores do sistema. Assim, em arquiteturas onde
a memória cache está associada somente à memória principal, não existem problemas de
coerência de memória cache. Podemos ver um diagrama da arquitetura com memórias
cache associadas em blocos ou associada somente à memória principal na Figura 3.4,
onde se pode observar duas arquiteturas de memória cache, uma com problema de co-
erência de dados 3.4(a) e outra sem problemas de coerência de dados 3.4(b) [20].
(a) Com problemas de coerência. (b) Sem problemas de coerência.
Figura 3.4. Arquiteturas de memória cache com problema de coerência de dados
3.4(a) e sem problemas de coerência de dados 3.4(b), adaptado de [20].
Paraque uma memória cache seja capaz de manter a coerência de dados, é necessária
a adoção de um protocolo de coerência para assegurar o controle de compartilhamento
Livro "Arquitetura de Computadores: Educação, Ensino e Aprendizado", 1ed.Porto Alegre: Sociedade Brasileira de Computação, 2012, v. 1, p. 74-110.
ISBN: 9788576692638
de qualquer bloco de dados entre várias memórias cache e processadores. Existem duas
classes principais de protocolos atualmente em uso para assegurar a coerência de memórias
cache:
• Baseadoem Diretório – O status sobre o compartilhamento de um bloco de memória
é alocado apenas em uma posição chamada diretório.
• Snooping – O status sobre o compartilhamento de um bloco é replicado em todas
as memórias cache que possuem a cópia de cada dado. Assim, não existe nenhum
diretório centralizador. Geralmente todas as memórias cache encontram-se em um
mesmo barramento e todos espionam (snoop) a movimentação no barramento, no
caso de alguma outra memória possuir cópia de blocos solicitados.
Como em diversos projetos de multiprocessadores as memórias cacheestão conec-
tadas a uma única memória principal interconectadas por um barramento, os protocolos
de coerência de memória cache mais populares são os baseados na técnica de snooping,
pois tiram proveito da infra-estrutura pré-existente. Como exemplo desse tipo de proto-
colo pode-se citar o protocolo MESI [5], sendo que o nome MESI vêm das iniciais dos
estados possíveis de um dado durante operação (modified, exclusive, shared, e invalid).
Os pontos-chave [21] de um barramento que possui suporte à coerência são que
todas as transações devem ser visíveis para todos os controladores de memória cache.
Assim, cabe ao protocolo de coerência garantir que todas as transações de memória
apareçam no barramento e que todos os controladores façam as ações necessárias ao
verem transações relevantes.
3.3.3. Modelos de Consistência
Os modelos de consistência de memória cache tratam o grau de consistência que dev-
erá existir no sistema, apresentando soluções sobre quando um valor atualizado em uma
memória cache qualquer deverá ser visível aos outros processadores.
Embora a questão sobre a consistência de dados na memória cache pareça trivial,
é de um elevado grau de complexidade, pois tratar a consistência de dados significa escol-
her o momento em que as variáveis devam ser atualizadas nas suas cópias. Porém, essa
escolha envolve também o algoritmo executado nos diversos processadores, além de ser
um tratamento sobre condição de corrida, uma vez que pode haver disputa por recursos.
O modelo mais simples de consistência de dados é o chamado consistência se-
qüencial, que é implementado de forma simples, e exige que um processador retarde a
conclusão de qualquer acesso à memória até que todas as invalidações causadas se com-
pletem.
Outro tipo de modelo também difundido é o modelo de consistência relaxado
[22], que envolve o programador ao gerar programas paralelos e consiste em permitir que
as leituras e gravações se completem fora de ordem, mas requer o uso de operações de
sincronização para impor ordenação, fazendo com que o programa seja sincronizado e
comporte-se como se estivesse em um processador mono-processado.
Livro "Arquitetura de Computadores: Educação, Ensino e Aprendizado", 1ed.Porto Alegre: Sociedade Brasileira de Computação, 2012, v. 1, p. 74-110.
ISBN: 9788576692638
3.3.4. Interconexões
Como os diversos dispositivos de um sistema, processadores, memórias, portas de entrada
e saída e demais dispositivos, precisam se comunicar, essa é a tarefa das interconexões.
Algumas das principais características de comparação entre interconexões são [20]:
• Escalabilidade – É uma característica desejável em toda interconexão. Diz respeito
a adaptabilidade da interconexão ao aumento da quantidade de dispositivos e tam-
bém de carga total de trabalho. Assim, um sistema escalável será de fácil expansão
mantendo as características principais inalteradas.
• Desempenho – O desempenho desejável de uma interconexão é que essa consiga
manipular e dar vazão a todos os dados em tempo hábil. Assim, o desempenho
indica a capacidade e a velocidade da transferência de dados pela interconexão.
• Custo – O custo de uma interconexão costuma variar proporcionalmente em função
do número de dispositivos interconectados e a capacidade de vazão e latência. Em
alguns casos, o custo de uma interconexão pode se referir à área ocupada pelo
projeto ou pela potência consumida.
• Confiabilidade – Pode ser tratada como a probabilidade da interconexão atender,
de forma adequada, aos dispositivos comunicantes. Assim, a existência de cam-
inhos alternativos ou redundantes entre dispositivos aumenta a confiabilidade da
interconexão.
• Funcionalidade – Diz respeito às funcionalidades específicas da interconexão agre-
gadas à transferência de dados. Assim, uma interconexão pode implementar outros
serviços como buffers de entrada e/ou saída, garantia de ordenação na transferência,
ou até mesmo roteamento automático.
• Reusabilidade – Trata da capacidade da interconexão se conectar a diferentes tipos
de dispositivos, e também da capacidade de que a cada nova geração o projeto poder
ser em grande parte reutilizado.
Uma interconexão pode ser feita de diversas formas e mesmo assim, durante anos,
a solução adotada tem sido a interconexão por barramento. Porém, atualmente existem
diversas formas de interconexões que estão sendo estudadas a fim de serem implemen-
tadas nos processadores multiprocessados, que é o caso das interconexões por matrizes
de chaveamento, ou por redes intra-chip, também conhecidas como NoC (Network-on-
Chip) [23].
3.3.5. Barramentos
Um barramento é um canal de comunicação compartilhado que utiliza um conjunto de
fios para conectar diversos dispositivos ou subsistemas. As principais vantagens dessa
interconexão é a simplicidade, reusabilidade e o baixo custo.
A simplicidade do barramento é considerada a partir do ponto de vista de que
novos dispositivos podem ser agregados facilmente sem grandes modificações, porém, o
Livro "Arquitetura de Computadores: Educação, Ensino e Aprendizado", 1ed.Porto Alegre: Sociedade Brasileira de Computação, 2012, v. 1, p. 74-110.
ISBN: 9788576692638
barramento não é totalmente escalável, pois o mesmo não se adapta para aumentar a vazão
de dados ao adicionar um novo componente interconectado.
Quanto à reusabilidade, como o projeto de barramentos muitas vezes segue a de-
terminados padrões, esses podem ser reusados a cada nova geração, com pouca ou nen-
huma modificação. Como o projeto de um barramento pode ser visto de forma simplista
como uma forma de compartilhamento de um conjunto de fios, essa interconexão é de
baixo custo.
A forma clássica de um barramento apresenta dois conjuntos de linhas de comu-
nicação, um conjunto de controle e outro conjunto de linhas de dados como é ilustrado na
Figura 3.5. As linhas de controle são usadas para gerenciar as requisições e confirmações,
além de informar o tipo dos dados que estão trafegando nas linhas de dados. As linhas de
dados são apenas linhas de propagação de informações entre origem e destino.
Figura 3.5. Diagrama de um barramento com canais de controle e dados interli-
gando processadores e memória cache a memória principal.
Como diversos componentes estão compartilhando um mesmo meio físico do bar-
ramento, o protocolo do barramento é contido nas linhas de controle, as quais implemen-
tam qual será a política de uso do barramento. O barramento também pode ser classificado
como rede dinâmica de interconexão, uma vez que a topologia de comunicação não existe
a priori.
3.3.6. Matrizes de Chaveamento
A matriz de chaveamento, também conhecida como crossbar ou crossbar switch possui
um custo elevado, porém, também é simples. Assim, embora uma rede de interconexão
possa ocupar grandes áreas do projeto para interligar um grande número de dispositivos,
essa interconexão se mantém simples uma vez que ao adicionar novas portas para dispos-
itivos não adiciona muita complexidade no controle. No entanto, a chave crossbar assim
como o barramento não é escalável como solução de interconexão global, o que dificulta
um projeto com quantidade elevada de núcleos de processamento.
A Figura 3.6 apresenta uma ilustração de uso de uma chavecrossbar interconectando
memórias cache de primeiro nível de diversos processadores com memórias cache L2
compartilhadas, cada um possuindo duas portas de comunicação. Dessa maneira, apenas
dois núcleos podem ser conectados a cada banco de memória cache simultaneamente.
Livro "Arquitetura de Computadores: Educação, Ensino e Aprendizado", 1ed.Porto Alegre: Sociedade Brasileira de Computação, 2012, v. 1, p. 74-110.
ISBN: 9788576692638
Figura 3.6. Diagrama de uma matriz de chaveamento interconectando proces-
sadores e memórias cache.
Em uma rede de chaveamento pode se interconectar dois dispositivos quaisquer,
desde que esses não se encontrem já ocupados. Uma alternativa para o alto custo é a
utilização de várias matrizes de chaveamento em formação hierárquica.
3.3.7. Redes Intra-Chip
Com a promessa de rápido aumento no número de núcleos de processamento dentro do
processador, aumenta a motivação de estudos sobre formas diferentes de interconexão
entre os vários dispositivos dentro do chip.
Com o intuito principal de aumentar a escalabilidade e reduzir o custo da inter-
conexão, diversos estudos abordam as redes de interconexão intra-chip. Em muitos casos,
essa rede de interconexão é formada por diversos roteadores, um em cada dispositivo, in-
terligados. Logo, podem não existir ligações diretas entre todos os dispositivos, sendo
necessário então que um pacote trafegue entre os roteadores para chegar ao seu destino.
A política de roteamento da interconexão é a que determina como os pacotes serão
chaveados para chegar ao destino. Assim, a forma de chaveamento depende da topologia
da rede de interconexão.
A Figura 3.7 apresenta um diagrama de utilização de uma rede de interconexão
intra-chip de tamanho 5x4 (20 roteadores), conectando diversos núcleos de processa-
mento a quatro bancos de memória cache. No caso ilustrado, o tempo de comunicação
entre núcleo e memória cache pode variar dependendo da localização do núcleo na rede
de interconexão, onde os núcleos mais próximos irão conseguir acessar a memória cache
com apenas dois saltos (hops), ou seja, passando apenas pelo roteador local e roteador da
memória cache, enquanto que nos piores casos, a comunicação poderá custar de 5 até 8
saltos, dependendo do banco de memória que o núcleo precisar acessar.
Livro "Arquitetura de Computadores: Educação, Ensino e Aprendizado", 1ed.Porto Alegre: Sociedade Brasileira de Computação, 2012, v. 1, p. 74-110.
ISBN: 9788576692638
Figura 3.7. Diagrama de uma rede de interconexão intra-chip (NoC) interligando
diversos núcleos de processamento.
3.4. Método de Avaliação de Memórias Cache Compartilhadas
De acordo com [24], a utilização de uma correta metodologia para avaliação de desem-
penho de sistemas computacionais evita diversos problemas, como a falta de objetivos,
objetivos viciados, abordagem não sistemática, análise sem compreender o problema,
métricas incorretas de desempenho, carga de trabalho não representativa, técnicas erradas
para avaliação, descaso com parâmetros importantes, ignorar fatores significantes, projeto
experimental inapropriado, entre outros. São diversos problemas que podem ocorrer, caso
não haja um correto planejamento dos experimentos.
Para evitar problemas em nosso projeto de avaliação, podemos seguir diversos
passos para assegurar que estamos efetuando as análises com rigor acadêmico. As etapas
a seguir foram adaptadas de [24] e aplicadas ao nosso projeto.
3.4.1. Definição do Sistema e Serviços
Esta etapa visa definir os objetivos do estudo delimitando o sistema a ser avaliado. A
Figura 3.8 apresenta um diagrama genérico do sistema de memória cache a ser avaliado,
onde estão definidos por blocos os principais componentes do sistema, como os núcleos
de processamento, a interconexão, o sistema de memória cache e a memória principal,
delimitando ainda o escopo que compreende ao processador, sendo que tais componentes
estão em um mesmo chip.
Figura 3.8. Definição do sistema a ser estudado.
Mesmo sem a definição clara da arquitetura e organização do sistema, com a vi-
sualização do diagrama do sistema a ser avaliado ficam evidentes os componentes não
Livro "Arquitetura de Computadores: Educação, Ensino e Aprendizado", 1ed.Porto Alegre: Sociedade Brasileira de Computação, 2012, v. 1, p. 74-110.
ISBN: 9788576692638
principais, mas que são relevantes ao estudo (núcleos de processamento, interconexão
e memória principal), e o componente principal do estudo que é o próprio sistema de
memória cache. Assim, o objetivo final do estudo é indicar formas de reduzir o impacto
do sistema de memória cache e melhorar o desempenho final do sistema.
Os serviços disponíveis aos núcleos de processamento através da interconexão ao
sistema de memória cache são definidos de forma sucinta como leitura e escrita de dados.
Estes serviços podem ser propagados até a memória principal. Os serviços devem oferecer
alto desempenho, evitando assim eventuais paradas dos núcleos de processamento.
3.4.2. Métricas de Avaliação
A escolha das métricas do sistema é importante, uma vez que através dessas métricas
as análises serão feitas e assim deve ser possível indicar qual sistema é apropriado para
cada situação, ou seja, as métricas devem ser pontos de comparação entre os sistemas
avaliados.
Algumas métricas para o sistema de memória cache são:
• Métricas de Desempenho
– Faltas de leituras de dados na memória cache.
– Faltas de escritas de dados na memória cache.
– Porcentagem de faltas de dados na memória cache.
– Faltas de dados na memória cache a cada mil instruções executadas (MPKI).
– Total de ciclos para a execução da carga de trabalho.
– Tempo total de execução da carga de trabalho.
– Tempo total de espera de dados por requisições de leitura e escrita.
– Tempo médio de atendimento das requisições de leitura e escrita.
– Número de instruções por segundo (MIPS).
– Número de operações de ponto flutuante por segundo (MFLOPS).
– Instruções prontas por ciclos de máquina (IPC).
• Métricas Físicas
– Área ocupada pela memória cache.
– Consumo de potência dinâmica do sistema de memória cache.
– Consumo de potência estática do sistema de memória cache.
3.4.3. Projeto de Experimentos
O objetivo de um projeto de experimento (DoE - Design of Experiment) correto é obter o
máximo de informações com o menor número de experimentos. Além disso, uma correta
análise desses experimentos também ajuda a identificar vários fatores ou os fatores que
mais influenciam no desempenho.
Alguns tipos de design existem e podem ser considerados para o estudo de desem-
penho computacional. Alguns deles são [24]:
Livro "Arquitetura de Computadores: Educação, Ensino e Aprendizado", 1ed.Porto Alegre: Sociedade Brasileira de Computação, 2012, v. 1, p. 74-110.
ISBN: 9788576692638
• Simple Design: É considerado um dos mais simples, consiste em variar um fator
por vez, e verificar como cada fator influência no desempenho.
• Full Factorial Design: Este modelo utiliza todas as combinações de fatores pos-
síveis e faz o mesmo para cada configuração possível.
• Fractional Factorial Design: Este modelo utiliza regras de escolha de combinações,
a fim de reduzir o número de experimentos, mesmo assim, essa técnica continua
gerando um bom nível de detalhamento dos resultados.
O modelo Fractional Factorial Design é um dos modelos mais indicados para
avaliação de desempenho, principalmente em sistemas simulados onde o número de ex-
perimentos deve ser controlado e não muito grande. Dentro deste modelo também existem
algumas sub-estratégias de projeto, como os designs fatoriais 2
k
, 2
k− p
, e os designs fato-
riais com replicação 2
k
r.
Após o estudo sobre os tipos de designs de experimentos, foi decidido utilizar
o modelo Fractional Factorial Design no projeto de avaliação de memórias cache, uma
vez que esse design se molda melhor aos requisitos de simulação e teste pretendidos, e a
escolha do sub-modelo foi feita de acordo com cada experimento pretendido, escolhendo
o mais adequado às necessidades.
3.5. Simulação de Sistemas Completos
A avaliação de desempenho pode ser classificada em modelagem de desempenho e medição
de desempenho [25], a modelagem de desempenho é tipicamente dividida em simulação
e modelagem analítica.
Assim, a avaliação de sistemas computacionais [24] pode ser feita de três maneiras
diferentes: modelagem analítica, simulação ou medições. A modelagem de desempenho
é tipicamente utilizada em estágios anteriores ao processo de projeto, quando os sistemas
ainda não estão disponíveis. Desta forma, medições só podem ser efetuadas se algum
sistema similar já estiver implementado. Não havendo protótipo disponível, simulações
são alternativas viáveis para sistemas completos enquanto modelos analíticos são mais
adequados para subsistemas.
Para os sistemas computacionais como subsistemas de memória, onde existem
muitas variáveis, a complexidade é muito alta, tornando difícil a criação de modelos
analíticos que representem corretamente o sistema. Além disso, modelos analíticos,
nesses casos, costumam apresentar baixa precisão.
Assim, a simulação se torna a ferramenta mais apropriada para estimar e comparar
características de diferentes organizações e arquiteturas de memórias, mantendo uma boa
precisão e boa generalização dos resultados obtidos.
3.6. Utilizando o Simics em Sala de Aula
O ambiente de simulação adotado foi o Simics da Virtutech AB [26], o qual foi escolhido
por ser um simulador completo de sistema no nível do conjunto de instruções.
Livro "Arquitetura de Computadores: Educação, Ensino e Aprendizado", 1ed.Porto Alegre: Sociedade Brasileira de Computação, 2012, v. 1, p. 74-110.
ISBN: 9788576692638
Atualmente para se obter o Simics, é necessária a submissão para a Virtutech e
aprovação, de um projeto utilizando o Simics, o que deve ser feito pelo orientador ou
professor responsável. O projeto pode ser tanto de pesquisa ou de uso em sala de aula e
deve conter informações básicas a respeito de uso e resultados esperados.
Após a submissão e aprovação, a Virtutech deverá entrar em contato liberando o
acesso para a download e instalação do Simics e também do servidor de licenças, nesse
caso, o servidor de licenças é do tipo flutuante, ou seja, ele trabalha com empréstimos de
licenças aos usuários. Uma vez recebido acesso aos recursos, é necessária a instalação do
servidor de licenças em algum servidor acessível pelos alunos.
A versão do Simics utilizada neste capítulo é a 4.0, assim, vamos nos limitar a
abordar apenas os detalhes relacionados a essa versão. Mesmo assim, são poucas as
modificações no ponto de vista do usuário entre as diferentes versões.
Uma das primeiras barreiras que podem aparecer em se tratando de utilização
de software com finalidade educacional, é o sistema operacional que o aluno costuma
utilizar. Nesse ponto, o Simics possui versões para alguns dos sistemas operacionais mais
utilizados: Linux, Windows e Solaris. Dessa forma, a escolha pela ferramenta pode ser
feita mais amplamente, pois não apresenta limitações nesse sentido.
A instalação atualmente é feita de maneira bastante intuitiva, portanto não será
discutida com muitos detalhes. Porém, sugerimos que no primeiro momento sejam insta-
lados todos os pacotes disponíveis além do pacote básico, tais pacotes dizem respeito à
máquina a ser simulada, como, por exemplo, X86, Sparc, Mips, etc. Porém, conforme for
adquirida mais experiência, pode-se apenas instalar o pacote específico a ser utilizado.
Depois de efetuada a instalação, faz-se necessária a configuração do workspace,
nesse ponto o aluno pode criar a área de trabalho no local de maior conveniência. Após
a criação do workspace, a pasta onde o mesmo foi criado, receberá diversos links para os
executáveis do Simics e também para as máquinas suportadas pela atual instalação.
Paraque os alunos possam utilizar o Simics, é necessário que eles definam em suas
máquinas as variáveis de ambiente: VTECH_LICENSE_FILE e LM_LICENSE_FILE
para o valor {porta}@{servidor_de_licenças}. Dessa maneira o Simics irá encontrar o
caminho para o servidor de licenças.
O simulador suporta a simulação completa de diversos tipos de máquinas e pro-
cessadores, Alpha, ARM, PPC, IA-64, x86, MIPS, Sparc V8, Sparc V9 e até UltraSparc
T1. Entretanto, para o melhor andamento do trabalho é sugerido que os alunos utilizem
apenas uma determinada máquina, facilitando assim, a interação entre os alunos e também
o trabalho de monitoria.
A escolha pela máquina e arquitetura dos processadores a serem simulados pode
ser feita considerando diversos fatores como: Sistema de propósito geral; Suporte a multi-
core; Suporte a ponto-flutuante; Suporte avançado à memória cache e; Suporte a ilimi-
tados núcleos de processamento. Desta maneira, apenas os sistemas Serengeti, SunFire
e x86-440BX apresentam as características necessárias esses requisitos. Segue abaixo a
descrição das três máquinas mais propícias para suportar as simulações de multi-core:
Livro "Arquitetura de Computadores: Educação, Ensino e Aprendizado", 1ed.Porto Alegre: Sociedade Brasileira de Computação, 2012, v. 1, p. 74-110.
ISBN: 9788576692638
• Serengeti: As classes de servidor Sun Fire 3800 - 6800 são modeladas, oferecendo
suporte nativo para até 24 processadores UltraSparc III, UltraSparc III Cu (III+), Ul-
traSparc IV, ou UltraSparc IV+. Essa máquina ainda oferece diversos componentes
PCI modelados, porém, suporta apenas sistemas operacionais Solaris, oferecendo
scripts para instalação do Solaris 8, 9 e 10.
• SunFire: Modela servidores da classe Sun Enterprise 3500 - 6500, com suporte
nativo para até 30 processadores UltraSparc II. Os sistemas operacionais Linux e
Solaris são suportados por esta máquina que também oferece scripts para instalação
do Solaris 8, 9 e 10.
• x86-440BX: Pode modelar vários sistemas com processadores x86 ou AMD64
baseado no chipset Intel 440BX. Suporta os sistemas operacionais Windows, Linux
e NetBSD. A BIOS customizada oferece suporte para até 15 processadores, porém,
é importante ressaltar que diversas versões de Linux são limitadas a 8 proces-
sadores, enquanto versões de Windows oferecem suportes variados a processadores
dependendo da versão do sistema operacional.
Após efetuar testes na máquina x86-440BX, foi verificado que não há condições
de executar sistemas operacionais com mais de 8 núcleos de processamento, seja por
problemas na compilação do kernel, seja por problemas internos no simulador. Além
disso, essa máquina com suporte a memória cache ativo, apresentou alguns problemas já
reportados como bugs pela Virtutech. Fora esses problemas, essa máquina apresenta um
tempo de simulação superior as duas outras eleita, por esses motivos, atualmente todos os
alunos são desencorajados a utilizarem a máquina x86-440BX em suas simulações, até
que os problemas citados sejam resolvidos.
Assim, são recomendadas apenas as máquinas SunFire e Serengeti para o uso dos
alunos. Aos alunos que necessitem eventualmente de outra máquina mais especifica em
seus experimentos, essa deve ser adotada com bastante cautela, observando atentamente
as limitações descritas no manual do usuário referente à máquina escolhida.
Algumas limitações do Simics são amplamente conhecidas, as principais são dadas
uma vez que o simulador Simics não modela todos os componentes de um hardware real,
já que o simulador trabalha no nível de conjunto de instruções.
Dessa forma, os resultados de tempo de execução no simulador são dados basi-
camente em instruções e ciclos. O número de ciclos é dado pelo número de instruções
executadas mais os ciclos em espera gerados pelas latências de todos os componentes
modelados. Normalmente a execução no simulador, desconsiderando os eventos de alta
latência, é de uma instrução por ciclo (parâmetro pré-definido pelo IPC), enquanto uma
máquina real consegue gerenciar a execução de mais instruções utilizando superescalari-
dade e outros componentes de desempenho.
Fora essa limitação, diversos componentes como barramentos, pré-busca e com-
portamentos do sistema, como gargalos de acesso a recursos, não são totalmente simula-
dos. Desse modo fica claro que o objetivo do simulador Simics é simular máquinas no
nível de conjunto de instruções e não efetuar uma simulação exata de todos dispositivos.
Livro "Arquitetura de Computadores: Educação, Ensino e Aprendizado", 1ed.Porto Alegre: Sociedade Brasileira de Computação, 2012, v. 1, p. 74-110.
ISBN: 9788576692638
Entretanto, o simulador é bastante útil para a comparação de execução de cargas de tra-
balho em diferentes organizações modeladas dentro do próprio simulador, uma vez que
as tendências ocorridas nas simulações devem se repetir em sistemas reais. Logo, o sim-
ulador Simics fornece um ambiente controlado e com determinismo controlado, propício
para avaliação de sistemas computacional futuros [27].
Algumas dessas limitações podem servir de inspiração aos alunos, como o fato
de não ser considerado a contenção de número de portas da memória, por exemplo, pode
intrigar o aluno e levá-lo a propor a criação de um modulo para que o Simics modele esse
comportamento de gargalo mais corretamente. Além desse exemplo, outros podem ser
pensados e sugeridos aos alunos, como forma de incentivo a criação de novos módulos e
melhorias na ferramenta.
3.6.1. Modos de Operação
Para simulação de memória cache, o Simics provê ferramentas bastante flexíveis para
configurar dispositivos. Em uma simulação de memória cache, o Simics permite tanto
observar informações a respeito de tempo, como a respeito das informações contidas na
memória. O simulador possui dois modelos pré-modelados de memórias cache: g-cache
e g-cache-ooo:
• O modelo g-cache fornece uma modelagem básica de uma memória cache ligada a
um processador executando as instruções em ordem e fornecendo relatórios sobre
as atividades realizadas.
• O modelo g-cache-ooo além das funcionalidades apresentadas pela g-cache, provê
ainda, a possibilidade de ser utilizada em simulações de processamento fora de
ordem (OOO - Out Of Order).
Mesmo com esses modelos pré-definidos de execução, é importante saber quais
dispositivos estão por trás ao executar os dois modelos pré-modelados, uma vez que
muitas vezes eses modelos não atendem a todas necessidades do experimento. Por esse
motivo, costuma-se não utilizar esses modelos prontos, e sim modelar o sistema e habilitar
o modo desejado do simulador.
Existem três modos de simulação aceitos pelo Simics: Normal, Stall e MAI. Esses
modos são habilitados na hora de executar o Simics pelas flags -fast, -stall e -mai respec-
tivamente, segue abaixo a descrição de cada um desses modos de operação:
• O modo Normal (-fast) fornece um ambiente de simulação onde não são considera-
dos os atrasos referentes à memória, além disso, esse modo não fornece estatísticas
de memória cache confiáveis uma vez que nem todos os acessos são registrados.
Este modo é bastante indicado para a preparação do ambiente de simulação, como
por exemplo, instalação de compiladores, compilação e testes preliminares do am-
biente de simulação. Além da preparação do ambiente, este modo também pode
ser utilizado para simulações onde se requer menor tempo de simulação e não é
necessário considerar as latências de memória, como para retirar traços de exe-
cução.
Livro "Arquitetura de Computadores: Educação, Ensino e Aprendizado", 1ed.Porto Alegre: Sociedade Brasileira de Computação, 2012, v. 1, p. 74-110.
ISBN: 9788576692638
• O modo Stall (-stall) é um modo de simulação mais lento que o modo normal, uma
vez que este modo considera o sistema de memória modelado e também faz o reg-
istro de todas as operações ocorridas nas memórias caches. Este modo é indicado
para ser utilizado apenas depois que o ambiente de simulação e a máquina a ser
simulada estejam totalmente configurados e prontos para os testes.
• O modo MAI (-mai) conhecido também como modo micro-arquitetura, é capaz de
prover simulação com execução de instruções fora de ordem (OOO). Embora este
modo seja bastante atraente, ele não costuma ser muito utilizado devido ao enorme
tempo de simulação exigido. Logo, este modo é mais indicado para simulações de
curtos trechos de execução, onde se quer analisar o comportamento de apenas um
método ou função.
Considerando que o principal objeto de estudo é o sistema de memória cache,
optou-se por não utilizar o modo MAI, uma vez que este modo levaria ao aumento signi-
ficativo de complexidade de simulação do processador o que acarretaria a problemas de
restrição de tempo, tornando proibitiva a simulação de aplicativos inteiros.
3.6.2. Modelagem de Memórias Cache
Um exemplo de modelagem de um processador com dois núcleos de processamento
com memórias cache de primeiro e segundo nível privadas para cada um dos núcleos
é ilustrado na Figura 3.9.
Figura 3.9. Diagrama de modelagem de um chip multi-core, adaptado de [28].
Na Figura 3.9 podemos ver os seguintes componentes internos do Simics respon-
sáveis pela correta simulação da memória cache:
• Id-splitter- Utilizado para fazer a separação entre instruções e dados para a memória
cache correta.
Livro "Arquitetura de Computadores: Educação, Ensino e Aprendizado", 1ed.Porto Alegre: Sociedade Brasileira de Computação, 2012, v. 1, p. 74-110.
ISBN: 9788576692638
• Splitter - Módulo responsável por particionar os dados, a fim de só alocar a quanti-
dade de dados coerente com o tamanho de memória.
• Trans-staller - Dispositivo simples, que simula a latência de acesso da memória
principal.
Além dos componentes inerentes à modelagem da memória cache no simulador,
podemos ver os seguintes componentes referentes ao modelo de controle de coerência de
estado das memória cache privadas:
• MESISnooper - Componente definido para indicar quais memórias cache de mesmo
nível devem utilizar o modo snooper a fim de manter coerência.
• Higher Level - Indica ao módulo de coerência do simulador quais memórias cache,
por exemplo memória cache L1, estão em níveis superiores e que se comunicarão
diretamente com cada memória cache de nível inferior, por exemplo memória cache
L2.
As interconexões utilizadas no simulador são transparentes, assim, pode-se con-
siderar que as conexões entre os componentes como processador e memória cache são
ponto a ponto. Entretanto, é possível definir uma latência para as interconexões de
memória cache, logo, todas as transações que tiverem que passar pela interconexão irá
causar latência ao sistema.
Os parâmetros de definição das latências de interconexões no Simics está agregada
com cada memória cache, essas latências são sempre definidas como latência para acessar
o próximo nível, ou seja, partindo do nível mais próximo do núcleo de processamento para
o nível inferior da memória.
Seguindoo exemplo de modelagem abaixo apresentado, os experimentos descritos
na próxima seção foram modelados, fazendo as devidas modificações na organização e
parâmetros das memórias cache de acordo com as características a serem estudadas e
avaliadas.
#===============================================================
## Inicialização de Parâmetros
#===============================================================
$num_cpus = 2
$cpu_class = "ultrasparc-iii-plus"
$clustered = "yes"
run-command-file "%simics%/targets/{machine}"
#===============================================================
## Gerador de Latências da Memória Principal
#===============================================================
@staller0 = pre_conf_object(’staller0’, ’trans-staller’)
@staller0.stall_time = 0
#===============================================================
## Memória Cache L2 - l2c0
#===============================================================
@l2c0 = pre_conf_object(’l2c0’, ’g-cache’)
@l2c0.cpus = [conf.cpu0]
@l2c0.config_line_number = 16384
@l2c0.config_line_size = 64
@l2c0.config_assoc = 8
@l2c0.config_virtual_index = 0
@l2c0.config_virtual_tag = 0
Livro "Arquitetura de Computadores: Educação, Ensino e Aprendizado", 1ed.Porto Alegre: Sociedade Brasileira de Computação, 2012, v. 1, p. 74-110.
ISBN: 9788576692638
@l2c0.config_write_back = 1
@l2c0.config_write_allocate = 1
@l2c0.config_replacement_policy = ’lru’
@l2c0.penalty_read = 0
@l2c0.penalty_write = 0
@l2c0.penalty_read_next = 0
@l2c0.penalty_write_next = 0
@l2c0.timing_model = staller0
#===============================================================
## Memória Cache de Instruções L1 - ic0
#===============================================================
@ic0 = pre_conf_object(’ic0’, ’g-cache’)
@ic0.cpus = conf.cpu0
@ic0.config_line_number = 1024
@ic0.config_line_size = 32
@ic0.config_assoc = 2
@ic0.config_virtual_index = 0
@ic0.config_virtual_tag = 0
@ic0.config_write_back = 0
@ic0.config_write_allocate = 0
@ic0.config_replacement_policy = ’lru’
@ic0.penalty_read = 0
@ic0.penalty_write = 0
@ic0.penalty_read_next = 0
@ic0.penalty_write_next = 0
@ic0.timing_model = l2c0
#===============================================================
## Memória Cache de Dados L1 - id0
#===============================================================
@dc0 = pre_conf_object(’dc0’, ’g-cache’)
@dc0.cpus = conf.cpu0
@dc0.config_line_number = 1024
@dc0.config_line_size = 32
@dc0.config_assoc = 2
@dc0.config_virtual_index = 0
@dc0.config_virtual_tag = 0
@dc0.config_write_back = 0
@dc0.config_write_allocate = 0
@dc0.config_replacement_policy = ’lru’
@dc0.penalty_read = 0
@dc0.penalty_write = 0
@dc0.penalty_read_next = 0
@dc0.penalty_write_next = 0
@dc0.timing_model = l2c0
#===============================================================
## Transaction Splitter para Memória Cache L1 de Instruções
#===============================================================
@ts_i0 = pre_conf_object(’ts_i0’, ’trans-splitter’)
@ts_i0.cache = ic0
@ts_i0.timing_model = ic0
@ts_i0.next_cache_line_size = 64
#===============================================================
## Transaction Splitter para Memória Cache L1 de Dados
#===============================================================
@ts_d0 = pre_conf_object(’ts_d0’, ’trans-splitter’)
@ts_d0.cache = dc0
@ts_d0.timing_model = dc0
@ts_d0.next_cache_line_size = 64
#===============================================================
## ID Splitter para Memória Cache L1
#===============================================================
@id0 = pre_conf_object(’id0’, ’id-splitter’)
@id0.ibranch = ts_i0
@id0.dbranch = ts_d0
#===============================================================
## Memória Cache L2 - l2c1
#===============================================================
@l2c1 = pre_conf_object(’l2c1’, ’g-cache’)
@l2c1.cpus = [conf.cpu1]
@l2c1.config_line_number = 16384
@l2c1.config_line_size = 64
@l2c1.config_assoc = 8
@l2c1.config_virtual_index = 0
@l2c1.config_virtual_tag = 0
@l2c1.config_write_back = 1
@l2c1.config_write_allocate = 1
@l2c1.config_replacement_policy = ’lru’
@l2c1.penalty_read = 0
@l2c1.penalty_write = 0
@l2c1.penalty_read_next = 0
@l2c1.penalty_write_next = 0
@l2c1.timing_model = staller0
Livro "Arquitetura de Computadores: Educação, Ensino e Aprendizado", 1ed.Porto Alegre: Sociedade Brasileira de Computação, 2012, v. 1, p. 74-110.
ISBN: 9788576692638
#===============================================================
## Memória Cache de Instruções L1 - ic1
#===============================================================
@ic1 = pre_conf_object(’ic1’, ’g-cache’)
@ic1.cpus = conf.cpu1
@ic1.config_line_number = 1024
@ic1.config_line_size = 32
@ic1.config_assoc = 2
@ic1.config_virtual_index = 0
@ic1.config_virtual_tag = 0
@ic1.config_write_back = 0
@ic1.config_write_allocate = 0
@ic1.config_replacement_policy = ’lru’
@ic1.penalty_read = 0
@ic1.penalty_write = 0
@ic1.penalty_read_next = 0
@ic1.penalty_write_next = 0
@ic1.timing_model = l2c1
#===============================================================
## Memória Cache de Dados L1 - id1
#===============================================================
@dc1 = pre_conf_object(’dc1’, ’g-cache’)
@dc1.cpus = conf.cpu1
@dc1.config_line_number = 1024
@dc1.config_line_size = 32
@dc1.config_assoc = 2
@dc1.config_virtual_index = 0
@dc1.config_virtual_tag = 0
@dc1.config_write_back = 0
@dc1.config_write_allocate = 0
@dc1.config_replacement_policy = ’lru’
@dc1.penalty_read = 0
@dc1.penalty_write = 0
@dc1.penalty_read_next = 0
@dc1.penalty_write_next = 0
@dc1.timing_model = l2c1
#===============================================================
## Transaction Splitter para Memória Cache L1 de Instruções
#===============================================================
@ts_i1 = pre_conf_object(’ts_i1’, ’trans-splitter’)
@ts_i1.cache = ic1
@ts_i1.timing_model = ic1
@ts_i1.next_cache_line_size = 64
#===============================================================
## Transaction Splitter para Memória Cache L1 de Dados
#===============================================================
@ts_d1 = pre_conf_object(’ts_d1’, ’trans-splitter’)
@ts_d1.cache = dc1
@ts_d1.timing_model = dc1
@ts_d1.next_cache_line_size = 64
#===============================================================
## ID Splitter para Memória Cache L1
#===============================================================
@id1 = pre_conf_object(’id1’, ’id-splitter’)
@id1.ibranch = ts_i1
@id1.dbranch = ts_d1
#===============================================================
# Níveis Superiores de Memória Cache
#===============================================================
@l2c0.higher_level_caches = [ic0,dc0]
@l2c1.higher_level_caches = [ic1,dc1]
#===============================================================
# Snoopers
#===============================================================
@l2c0.snoopers = [l2c1]
@l2c1.snoopers = [l2c0]
#===============================================================
# Criação de Espaços de Memória para os Núcleos
#===============================================================
@mem0 = pre_conf_object(’cpu0_space’,’memory-space’)
@mem1 = pre_conf_object(’cpu1_space’,’memory-space’)
#===============================================================
# Instanciação dos Componentes
#===============================================================
@SIM_add_configuration([staller0,l2c0,mem0,ic0,dc0,ts_i0,ts_d0,id0,l2c1,mem1,ic1,dc1,ts_i1,ts_d1,id1], None);
Livro "Arquitetura de Computadores: Educação, Ensino e Aprendizado", 1ed.Porto Alegre: Sociedade Brasileira de Computação, 2012, v. 1, p. 74-110.
ISBN: 9788576692638
#===============================================================
# Ligação dos Modelos de Tempo
#===============================================================
@conf.cpu0_space.default_target = [conf.phys_mem, 0, 0, conf.phys_mem]
@conf.cpu0.physical_memory = conf.cpu0_space
@conf.cpu0_space.timing_model = conf.id0
@conf.cpu1_space.default_target = [conf.phys_mem, 0, 0, conf.phys_mem]
@conf.cpu1.physical_memory = conf.cpu1_space
@conf.cpu1_space.timing_model = conf.id1
#===============================================================
Como o simulador trabalha em nível de conjunto de instruções, as penalidades
para os diversos componentes simulados são definidos em termos de ciclo de relógio.
Desta maneira, uma latência de leitura de dados deve ser modelada em termos de ciclos,
considerando a freqüência que se deseja modelar e o tempo de acesso.
Uma importante ferramenta para estimar parâmetros de memória cache e memória
principal é o software Cacti [29]. Assim, pode-se modelar todas as estimativas de tempo
de acesso às memórias considerando as estimativas de latência fornecidas por essa ferra-
menta. Para modelar uma memória corretamente no Cacti, deve-se fornecer informações
como a tecnologia de integração, freqüência de operação e outros parâmetros os quais de-
vem ser definidos previamente para os experimentos e podem ser desenvolvidos em sala
de aula com os alunos.
3.6.3. Discos, Imagens e Checkpoints
Ao instalar os pacotes do Simics, pode-se notar que diversas máquinas não funcionam
corretamente por falta da imagem do disco rígido. Isso acontece, pois essas imagens
costumam ser bastante grandes e por isso a Virtutech disponibiliza os arquivos de imagem
separados, apenas na seção de downloads do site www.simics.net.
Dessa maneira, ao fornecer a ferramenta de simulação aos alunos, é importante
fornecer também informações sobre como conseguir essas imagens de discos que já pos-
suem um sistema operacional instalado. Assim, os alunos poderão avançar mais rapida-
mente para a parte de modelagem e simulação, diminuindo assim possíveis atrasos que
essa etapa de instalação e configuração possa causar ao projeto.
Seguindo o exemplo da Virtutech, que disponibiliza sistemas pré-configurados
para as máquinas a serem simuladas. Os professores ou monitores da disciplina podem
deixar imagens de sistemas prontos com as ferramentas básicas necessárias aos alunos,
para que essa etapa não consuma muito tempo do projeto.
Para a criação dessas máquinas pré-configuradas, existem dois tipos de arquivos
básicos de imagem de discos rígidos no Simics, os arquivos do tipo craff e os arquivos do
tipo disk. Esses dois tipos de arquivos são gerados pelo próprio simulador, e podem ser
gerados para qualquer sistema configurado, de forma que os alunos podem apenas obter
esses arquivos e conectar em suas simulações.
Os arquivos do tipo craff, costumam ser de pacotes mais consolidados como os
cedidos pela Virtutech para download e devem ser colocados em pasta especifica dentro
da instalação do Simics. Já as instalações feitas pelo usuário costumam ser do tipo disk
e essas precisam apenas ser copiadas para dentro do workspace do usuário, para que
comecem a funcionar.
Livro "Arquitetura de Computadores: Educação, Ensino e Aprendizado", 1ed.Porto Alegre: Sociedade Brasileira de Computação, 2012, v. 1, p. 74-110.
ISBN: 9788576692638
Além desses dois tipos de arquivos de imagem, o aluno pode ainda gerar cópias
de segurança durante a simulação, seja do estado persistente do disco rígido ou de todo
contexto simulado, registradores, disco, memória, etc.
Para a gravação de estados persistentes, é importante que o disco a ser salvo esteja
sincronizado, ou seja, todos os dados devem sofrer um write-back para o disco rígido, e
então se pode utilizar os comandos, save-persistent-state para gravar ou load-persistent-
state, para carregar o estado do disco rígido da máquina simulada. No Linux por exemplo,
o aluno pode fazer a sincronização como o comando sync, ou então desligando a máquina
simulada.
Para a criação de checkpoints das máquinas simuladas, com todos dados da exe-
cução, deve-se utilizar os comandos write-configuration para salvar e read-configuration
para carregar o ponto de restauração salvo. No entanto, esse modo de salvamento não
permite que a arquitetura seja modificada, pois isso poderia criar inconsistências na sim-
ulação.
Como esse recurso de criação de estados persistentes, a preparação do ambiente
pode ser feita em uma simulação simples, diferente da modelagem da máquina final.
Dessa forma, a simulação tende ser mais veloz, e então, somente ao final da preparação
do ambiente deve-se criar um estado persistente o qual irá manter as modificações no
disco rígido simulado.
Após a completa configuração do sistema, chega a hora de modelar a arquitetura
que for adequada para os experimentos e carregar o estado persistente previamente criado.
Assim, ao final da carga do sistema ou durante os testes, o usuário também pode criar
eventuais pontos de checagem como forma de backup ou até mesmo auxílio durante a
simulação.
3.6.4. Inserindo Arquivos no Ambiente Simulado
Uma das funções básicas para uma simulação completa é a inserção de arquivos no am-
biente simulado. O simulador Simics permite a inserção de arquivos de três maneiras
distintas, por módulo de kernel, rede local ou imagem de CD-ROM. Os estados persis-
tentes de discos rígidos disponibilizados pela Virtutech possuem uma preparação especial
do sistema operacional, onde o módulo de kernel chamado SimicsFS carregado ao ker-
nel permite que dentro da simulação o usuário possa montar o sistema de arquivos da
máquina hospedeiro, ou seja, onde se encontra instalado o Simics.
Mesmo com a facilidade que um módulo já incorporado ao kernel possa propiciar,
ao montar um ambiente de simulação começando desde a instalação do sistema opera-
cional, a tarefa de compilar o kernel com o módulo SimicsFS pode não ser muito fácil.
Assim, o usuário ainda conta com duas alternativas para carregar os arquivos para den-
tro da simulação, ou habilitando a rede do hóspede (máquina que está sendo simulada)
e ativando o suporte do Simics para conexão com a rede real. Ou então, ainda pode-
mos contar com a inserção dos arquivos pela simulação de uma unidade de CD-ROM na
máquina simulada, para isso, basta criar um arquivo de imagem do tipo ISO (mkisofs -l
-o New-Image.iso -r Files-to-image), e então utilizar os comandos, (new-file-cdrom file =
New-Image.iso), para criar um CD virtual com o arquivoiso e então o comando (cd0.insert
Livro "Arquitetura de Computadores: Educação, Ensino e Aprendizado", 1ed.Porto Alegre: Sociedade Brasileira de Computação, 2012, v. 1, p. 74-110.
ISBN: 9788576692638
media = New-Image) para inserir o CD virtual no dispositivo de CD-ROM da máquina
simulada.
3.6.5. Magic Instruction
O Simics fornece uma maneira de interação entre simulação e simulador bastante sim-
ples e eficiente, conhecida como Magic Instruction. A Magic Instruction nada mais é
que uma biblioteca com as funções MAGIC e MAGIC_BREAKPOINT, essas funções
quando chamadas, elas executam um código em linguagem de montagem que não mod-
ifica nenhum registrador, mas é reconhecido pelo simulador como sendo a chamada da
Magic Instruction e então efetua a tarefa indicada.
Um código simples de HelloWorld.c em OpenMP com a chamada para a Magic
Instruction segue abaixo:
//-------------------HelloWorld.c-------------------\\
#include <stdio.h>
#include <stdlib.h>
#include <omp.h>
#include "magic-instruction.h"
int main (int argc, char
*
argv[]) {
int t_id;
MAGIC(1);
#ifdef _OPENMP
printf("Executando: OpenMP -> %d threads\n",
omp_get_max_threads());
#else
printf("Executando: Normal -> 1 thread\n");
#endif
#ifdef _OPENMP
#pragma omp parallel private(t_id)
{
#endif
t_id = omp_get_thread_num();
printf("Oi mundo da thread %d\n", t_id);
#ifdef _OPENMP
} /
*
Sincronizacao
*
/
#endif
printf("Isso eh impresso por apenas uma thread.\n");
MAGIC_BREAKPOINT;
}
No código HelloWorld.c, é importante notar que foi incluída a biblioteca magic-
instruction.h no inicio do código, e então foram utilizadas as chamadas MAGIC(1) e
MAGIC_BREAKPOINT. A função MAGIC(1) irá retornar para o Simics e executar se
disponível alguma função de callback pré-definida. Já a função MAGIC_BREAKPOINT
faz com que a simulação pare ao executar essa função. Dessa maneira, com essas funções
a gama de possibilidades de uso do simulador aumenta bastante, uma vez que o usuário
pode instrumentar qualquer código a fim de interagir com o sistema simulado. Ressaltando
que a biblioteca magic-instruction.h está contida no pacote de instalação do Simics.
Abaixo segue a definição da função em Python no Simics para ser executada du-
rante o callback da função MAGIC():
@def a_callback(user_arg, cpu, arg):
print "numero de ciclos", cpu.cycles
SIM_run_command_file("FuncaoA.simics")
@SIM_hap_add_callback("Core_Magic_Instruction", a_callback, None)
A função de callback recebe a chamada da Magic Instruction e então executa os
comando do arquivo FuncaoA.simics que pode conter funções em Python ou CLI.
Livro "Arquitetura de Computadores: Educação, Ensino e Aprendizado", 1ed.Porto Alegre: Sociedade Brasileira de Computação, 2012, v. 1, p. 74-110.
ISBN: 9788576692638
3.6.6. Modo de Busca de Instruções
Algumas configurações são necessárias em se tratando de simulação de memórias cache
a fim de conseguir resultados coerentes e mais próximos da realidade. Nesse sentido, a
busca de instruções no simics pode ser habilitada ou desabilitada pelo usuário de acordo
com suas necessidades de simulação.
Tal configuração é feita pelo comando ifm (instruction fetch mode), esse comando
seleciona como as buscas de instrução serão enviadas para a hierarquia de memória du-
rante a simulação. Se configurado para no-instruction-fetch, a hierarquia de memória não
irá receber nenhuma busca de instruções durante a simulação. Caso configurado para
instruction-cache-access-trace, a hierarquia de memória irá receber uma e apenas uma
busca de para cada nova linha de dados acessada, onde o tamanho dessa linha da memória
cache é definida pelo atributo instruction-fetch-line-size dentro do processador. Por fim,
caso a busca de instruções for configurada para instruction-fetch-trace, todas as buscas de
instrução serão visíveis.
Mesmo esse comando sendo bastante interessante, nem todos os níveis de config-
uração citados estão disponíveis em todas as arquiteturas simuladas, devendo ser consul-
tado o manual para cada arquitetura a fim de saber a disponibilidade.
Uma vez que os atuais processadores utilizam mecanismos de pre-fetch, é impor-
tante ponderar o uso do modo de busca de instruções, onde por um lado pode ser mais
realístico o registro de busca apenas quando uma nova linha de memória é acessada, ou
por outro lado, o registro de todas as buscas, com latências reduzidas podem gerar mel-
hores aproximações. Assim, é importante a discussão em sala de aula, sobre os modos
de busca de dados, e qual o modo deverá ser adotado a fim de gerar uma simulação mais
realística e envolver os alunos no tema, gerando um pensamento mais crítico sobre as
arquiteturas e seus mecanismos.
3.6.7. Métricas e configurações de execução
Uma vez que o Simics trabalha em nível de conjunto de instruções, o simulador não
é capaz de indicar qual será o IPC da máquina simulada, uma vez que os estágios de
um pipeline, por exemplo, não são simulados. Porém, o simulador permite que sejam
configurados diversos mecanismos a respeito da execução durante a simulação.
A primeira configuração necessária para uma simulação mais realista é o tempo
de troca de execução entre processadores/núcleos. Essa configuração existe por causa da
forma de implementação do simulador, e pode influenciar o tempo de simulação.
O Simics, trabalha com múltiplos processadores da seguinte forma. Tomando
o caso hipotético de 4 processadores sendo simulados, o Simics irá executar N ciclos
do processador 0, N ciclos do processador 1, e assim por diante, em um esquema de
fila circular. Para simulações onde não estamos interessados exatamente no efeito das
memórias cache, ou o tempo exato de simulação não é importante, o número de passos
executados N pode ser grande. Já nos casos onde queremos ter resultados mais precisos,
deve-se usar N = 1.
O comando para definir o tempo dessa troca de execução é o cpu-switch-time
cycles, o qual é indicado utilizar valor igual a 1 apenas quando estamos com todo ambiente
Livro "Arquitetura de Computadores: Educação, Ensino e Aprendizado", 1ed.Porto Alegre: Sociedade Brasileira de Computação, 2012, v. 1, p. 74-110.
ISBN: 9788576692638
de simulação pronto, e queremos fazer testes em nossa arquitetura. Dessa maneira, com
cada processador executando 1 ciclo por vez, a simulação pode gerar resultados mais
próximos da realidade, porém essa troca de execução é custosa no ponto de vista de tempo
de simulação.
Após a configuração do tempo de troca de execução entre processadores, outro
parâmetro importante que pode ser configurado no Simics é a quantidade de instruções
executadas por ciclo (IPC) de cada processador. Essa configuração pode ser feita pelo
método set-step-rate de cada processador, onde a configuração padrão é igual a 1. Com
esse parâmetro, pode-se executar uma dada aplicação em uma máquina real, obter o seu
IPC e então configurar no Simics, fazendo uma configuração fina para a simulação. Essa
configuração também pode ser utilizada em inúmeras experiências, como por exemplo,
simulação de núcleos heterogêneos, onde um ou mais núcleos tem uma capacidade de
computação diferente dos demais.
Para suportar essas configurações de IPC, três conceitos são utilizados para simu-
lação: step, cycles e time. O entendimento desses conceitos é fundamental para alunos de
arquiteturas, e pode ser exercitado utilizando o simulador.
O número de steps nada mais é que o número de instruções completadas ou ex-
ceções ocorridas. Ou seja, são as instruções completadas somadas com as instruções que
não foram completadas por que alguma exceção ocorreu. Onde cada instrução irá contar
como um step.
A quantidade de cycles é o número de ciclos executados desde que a máquina sim-
ulada foi ligada. A quantidade de cycles e steps não são necessariamente iguais, uma vez
que uma instrução pode gerar eventos de alta latência como acesso à memória, além do
que esse número pode ser influenciado também pelo IPC configurado para o processador.
O time dentro do simulador não é influenciado pela máquina em que a simulação
está sendo executada (máquina hospedeira). De forma que hospede e hospedeiro são to-
talmente independentes. Para a atualização do tempo dentro da simulação, é utilizada
a quantidade de cycles dividida pela freqüência definida para o processador. Essa inde-
pendência é importante para que o simulador se mantenha determinístico, e assim, inde-
pendente da carga de trabalho que a máquina hospedeira esteja executando, o simulador
deverá retornar sempre resultados coerentes da simulação.
Considerando o isolamento da máquina simulada, podemos notar que os resulta-
dos de desempenho de uma simulação podem ser vistos tanto dentro do simulador, como
se estivesse em um sistema real, o então o aluno pode utilizar as Magic Instruction dentro
do código a ser executado e então obter o número exato de ciclos de execução. A segunda
alternativa, efetuando a instrumentação do código com Magic Instruction, é considerado
o modo mais preciso e interessante para que sejam feitas medições de desempenho. Uma
vez que, uilizando Magic Instruction, pode-se além de automatizar o processo de geração
de estatísticas e relatórios, esse modo permite também obter mais resultados, como as
estatísticas da memória cache do simulador.
As estatísticas da memória cache disponíveis no Simics são obtidas por métodos
que podem ser executados em qualquer objeto de memória cache no Simics, abaixo segue
a lista e breve descrição das principais estatísticas disponíveis:
Livro "Arquitetura de Computadores: Educação, Ensino e Aprendizado", 1ed.Porto Alegre: Sociedade Brasileira de Computação, 2012, v. 1, p. 74-110.
ISBN: 9788576692638
• stat_copy_back - Número de transações de copy-back iniciadas pela memória cache.
• stat_data_read - Número de leituras de dados na memória cache
• stat_data_read_miss - Número de leituras de dados que não estavam na memória
cache.
• stat_data_write - Número de escritas de dados na memória cache
• stat_data_write_miss - Número de escrita de dados que não estavam na memória
cache.
• stat_inst_fetch - Número de busca de instruções na memória cache.
• stat_inst_fetch_miss - Número de busca de instruções que não estavam na memória
cache.
• stat_mesi_exclusive_to_shared - Número de operações do protocolo MESI do tipo:
Exclusivo para Compartilhado.
• stat_mesi_invalidate - Número de operações de invalidações de dados do protocolo
MESI.
• stat_mesi_modified_to_shared - Número de operações do protocolo MESI do tipo:
Modificado para Compartilhado.
• stat_transaction - Número total de transações observadas pela memória cache.
3.6.8. Determinismo nas Simulações
A etapa de resultados de uma avaliação de desempenho é uma das mais importantes,
uma vez que todos os dados e as análises feitas acerca dos dados devem ser compilados
e apresentados de forma clara e objetiva. Justamente nesta etapa é que ocorrem muitos
erros ligados à avaliação do sistema computacional [24], como ignorar a variação das
medidas, apresentação dos resultados de forma incorreta, assim como omitir as limitações
do sistema.
Por isso, quando estamos trabalhando em sistemas reais, normalmente são feitas
múltiplas medições, e técnicas estatísticas são utilizadas para garantir que as medições são
estatisticamente significantes. Logo, o objetivo dessa metodologia é garantir que efeitos
causados por fatores não controlados, não levem a falsas conclusões.
Assim, ao trabalhar com um simulador determinístico, onde todas as execuções
de uma mesma aplicação iniciadas de um mesmo checkpoint vão retornar os mesmos
resultados, uma vez que o simulador irá executar as mesmas operações e sofrer de mesmas
latências do hardware, como é o caso do Simics, poderíamos considerar que temos um
resultado plausível a partir de apenas uma medição. Entretanto, devemos considerar que
o fato do simulador ser determinístico não garante que a carga de trabalho também será
determinística. Ou seja, pequenas variações iniciais do estado do simulador podem levar a
carga de trabalho ou o sistema operacional a caminhos de execução diferentes [30], dessa
maneira, a execução única do experimento pode levar a falsas conclusões.
Livro "Arquitetura de Computadores: Educação, Ensino e Aprendizado", 1ed.Porto Alegre: Sociedade Brasileira de Computação, 2012, v. 1, p. 74-110.
ISBN: 9788576692638
Logo, certos cuidados devem ser tomados na simulação com relação à variação
dos resultados obtidos, uma vez que o simulador que estamos utilizando é determinís-
tico. Para inserção de não-determinismo entre as execuções, cada aplicação pode, por
exemplo, ser executada a partir de diferentes checkpoints, fazendo assim o sistema agir de
forma não-determinística, pelas interrupções causadas pelo sistema operacional, levando
assim, as cargas de trabalho a diferentes caminhos de execução. Para essa forma de exe-
cução, podemos após cada execução de uma determinada aplicação, criar um checkpoint
diferente, a partir do qual a próxima execução e medição daquela mesma aplicação será
feita.
Além da preocupação em relação ao determinismo do sistema, pode-se também
planejar reduzir possíveis efeitos transientes [31] executando previamente cada aplicação
da carga de trabalho, a fim de aquecer a memória cache, salvando o estado do sistema
após essa primeira execução de cada aplicação. Então, somente a partir desse estado
salvo, executa-se e mede-se cada aplicação da carga de trabalho.
3.6.9. Fluxo de Projeto Proposto
Após apresentar os conceitos e funcionalidades do simulador, é importante fixar um fluxo
de projeto para que os alunos possam se guiar durante a execução do projeto proposto.
Assim, com a experiência ganha após alguns testes e avaliações com o Simics, foi
desenvolvido o fluxo de projeto apresentado na Figura 3.10.
Figura 3.10. Diagrama do fluxo de simulação proposto.
O fluxo de projeto apresentado não considera as etapas de design de experimentos
nem de análise estatísticas, sendo que essas etapas podem ser agregadas aos projetos, na
forma que mais for conveniente ao professor. Porém, as etapas apresentadas no diagrama,
auxiliam os alunos no sentido de viasualizar toda a organização do método de trabalho
utilizando o simulador, de forma que, utilizando os passos apresentados, os alunos tendem
a reduzir o tempo total do projeto.
Livro "Arquitetura de Computadores: Educação, Ensino e Aprendizado", 1ed.Porto Alegre: Sociedade Brasileira de Computação, 2012, v. 1, p. 74-110.
ISBN: 9788576692638
3.7. Estudo de Casos
Nesta seção será apresentado um estudo de caso de avaliação de memórias cache em
multi-core utilizando o Simics, que serviu de experiência para a adoção do simulador no
ensino de arquiteturas. Também serão mostrados como exemplo, seis trabalhos apresenta-
dos pelos alunos, dividido pelos dois anos ministrados da disciplina chamada Introdução
ao Processamento Paralelo e Distribuído, da Pós-Graduação em Computação da Univer-
sidade Federal do Rio Grande do Sul.
Com a contínua demanda por desempenho computacional, as memórias cache
vêm sendo largamente adotadas nos diversos tipos de projetos arquiteturais de computa-
dores. Os atuais processadores disponíveis no mercado apontam na direção do uso de
memórias cache L2 compartilhadas. No entanto, ainda não esta claro quais os ganhos e
custos inerentes desses modelos de compartilhamento da memória cache. Assim, nota-
se a importância de estudos que abordem os diversos aspectos do compartilhamento de
memória cache em processadores com múltiplos núcleos.
Portanto, esse estudo de caso visou avaliar diferentes compartilhamentos de memória
cache, modelando e aplicando cargas de trabalho sobre as diferentes organizações, a fim
de obter resultados significativos sobre o desempenho e a influência do compartilhamento
da memória cache em processadores multi-core.
Para isso, foram avaliados diversos compartilhamentos de memória cache, uti-
lizando o simulador Simics, avaliando técnicas tradicionais de aumento de desempenho,
como aumento da associatividade, maior tamanho de linha, maior tamanho de memória
cache e também aumento no número de níveis de memória cache, investigando a corre-
lação entre essas arquiteturas de memória cache e os diversos tipos de aplicações da carga
de trabalho avaliada.
Os resultados mostraram a importância da integração entre os projetos de arquite-
tura de memória cache e o projeto físico da memória, a fim de obter o melhor equilíbrio
entre tempo de acesso à memória cache e redução de faltas de dados. Notou-se nos
resultados, dentro do espaço de projeto avaliado, que devido às limitações físicas e de
desempenho, as organizações 1Core/L2 e 2Cores/L2, com tamanho total igual a 32 MB
(bancos de 2 MB compartilhados), tamanho de linha igual a 128 bytes, representam uma
boa escolha de implementação física em sistemas de propósito geral, obtendo um bom
desempenho em todas aplicações avaliadas sem grandes sobrecustos de ocupação de área
e consumo de energia.
Além disso, como conclusão deste estudo de caso, mostrou-se que, para as atuais
e futuras tecnologias de integração, as tradicionais técnicas de ganho de desempenho
obtidas com modificações na memória cache, como aumento do tamanho das memórias,
incremento da associatividade, maiores tamanhos da linha, etc. não devem apresentar
ganhos reais de desempenho caso o acréscimo de latência gerado por essas técnicas não
seja reduzido, a fim de equilibrar entre a redução na taxa de faltas de dados e o tempo de
acesso aos dados.
Nos trabalhos desenvolvidos pelos alunos apresentados a seguir, foi utilizado o
simulador Simics, simulando sistemas operacionais Linux ou Solaris com compiladores
GNU GCC ou Sun Studio respectivamente.
Livro "Arquitetura de Computadores: Educação, Ensino e Aprendizado", 1ed.Porto Alegre: Sociedade Brasileira de Computação, 2012, v. 1, p. 74-110.
ISBN: 9788576692638
Inicialmente os alunos utilizaram arquiteturas de processadores dual-core e quad-
core conhecidas, sem efetuar mudanças que representassem alterações ou uma nova pro-
posta de arquitetura. As configurações principais de três trabalhos feitos no primeiro ano
que a disciplina adotou o Simics para auxilio no ensino são descritas a seguir:
Um primeiro trabalho, do primeiro ano modelou um processador quad-core AMD
Opteron de 64 bits. As memórias cache L1 são locais a cada núcleo, possuem tamanho
de 128 kB cada e não são privadas. A memória cache L2 possui tamanho de 512 kB
e é compartilhada entre todos os núcleos. Os ciclos de penalidade para cada memória
são: 3 ciclos para memória cache L1, 10 ciclos para memória cache L2 e 60 ciclos para
a memória principal. Além da modelagem no simulador, foi desenvolvido um programa
paralelo em OpenMP para decodificação de MP3.
Em um segundo trabalho, do primeiro ano foi modelado um processador dual-
core Pentium 4 de 2GHz. Onde cada núcleo possui uma memória cache L1 de 64 kB e os
dois núcleos compartilham uma memória cache L2 de 2 MB. Foi utilizado uma latência
de 3 ciclos para a memória cache L1 e 14 ciclos para a memória cache L2. Neste tra-
balho o aluno estudou a organização do Intel Core Duo, núcleo Yonah, para especificar as
latências do projeto. A aplicação avaliada nesta arquitetura foi um decodificador MPEG
paralelizado através de MPI.
Um terceiro trabalho, do primeiro ano foi focado na arquitetura UltraSparc II.
O aluno modelou um processador com quatro núcleos, mantendo também a tendência
mostrada nos trabalhos anteriores de compartilhamento de memória cache L2 e memórias
cache L1 locais e privadas. No entanto o aluno desenvolveu dois modelos, no primeiro a
memória cache L2 é compartilhada entre todos os quatro núcleos, no segundo a memória
cache L2 é dividida em duas, sendo que apenas dois núcleos compartilham cada uma
delas. No primeiro modelo a memória cache L1 possui 32 kB e a memória cache L2
possui 1024 kB. No segundo modelo a memória cache L1 permanece com o mesmo
tamanho, mas as memórias cache L2 possuem agora 512 kB cada uma. Neste trabalho, o
aluno desenvolveu e avaliou um programa para convolução de imagens escrito em MPI.
Ao final do primeiro ano, notamos que o projeto da arquitetura dos processadores
poderia ser mais bem elaborado pelos alunos nos próximos semestres, uma vez que a pro-
posta da disciplina deixaria de ser uma novidade fazendo com que os próximos alunos
tenham uma real noção do grau de dificuldade e do tempo necessário para realização do
projeto. Além disto, trabalhos com o grau de dificuldade e/ou profundidade já apresen-
tados deveriam ser melhorados. Portanto, seria solicitado e esperado, que os próximos
trabalhos fossem mais complexos.
A introdução ao Simics e o suporte dado aos alunos se mostrou eficiente. No
entanto, percebeu-se a necessidade de introduzir o ambiente de simulação logo no início
da disciplina, mesmo antes do ensino teórico sobre arquiteturas paralelas, o que foi feito
no segundo ano adotando a ferramenta de simulação. A atividade de monitoria também
foi mais incentivada, para que os alunos pudessem tirar dúvidas mais rapidamente.
Assim, no segundo ano da disciplina, o método de ensino do simulador evoluiu,
onde mais materiais didáticos foram preparados e algumas formas de apresentar o simu-
lador e exigir projetos também evoluíram. Neste segundo ano, também foi aperfeiçoado o
Livro "Arquitetura de Computadores: Educação, Ensino e Aprendizado", 1ed.Porto Alegre: Sociedade Brasileira de Computação, 2012, v. 1, p. 74-110.
ISBN: 9788576692638
ambiente a ser disponibilizado aos alunos, parte foi feito previamente, e partes feitas sob
demanda, de forma a gerar um processo de melhorias continuas ao longo dos anos usando
a ferramenta.
Além disso, nesse segundo ano, foram indicadas duas aplicações CG e BT da
carga de trabalho paralela NAS para que os alunos pudessem avaliar as arquiteturas ap-
resentadas. Além disso, com a escolha de uma mesma carga de trabalho para todos os
alunos efetuarem testes, planeja-se criar um espírito competitivo a cada ano, a fim de
motivar os alunos a criarem propostas cada vez mais interessantes.
A seguir são apresentados três novos trabalhos feitos pelos alunos no segundo ano
em que o Simics foi adotado como ferramenta didática na disciplina.
Um primeiro trabalho, do segundo ano avaliou a diferença de desempenho de ar-
quiteturas de três e quatro níveis de memória cache, e propôs uma hierarquia entrelaçada
de memória. O aluno verificou que, nas situações simuladas, é mais interessante adicionar
um quarto nível de memória cache e dividir o terceiro em dois módulos, do que simples-
mente aumentar o tamanho da memória cache L3. Notando que o comportamento se deve
ao menor tempo de acesso e a menor contenção pelo acesso a L3 presente nas arquiteturas
com memória cache L4 simuladas.
Em um segundo trabalho, do segundo ano o aluno teve como objetivo, avaliar a
influência de se adicionar um nodo gargalo em um sistema de processamento distribuído,
no caso, o aluno criou uma pequena rede particular com 4 nodos simulados, onde foram
avaliadas diferentes configurações de nodos com diferentes capacidades de processa-
mento. Os resultados, diferente do esperado não mostraram perdas de desempenho ao
adicionar o nodo gargalo na pequena rede, mesmo assim, o aluno usou esses resultados
como motivação para criar uma nova metodologia de avaliação para atacar novamente o
problema.
Um terceiro trabalho, do segundo ano apresentou diversas simulações de arquite-
turas de multi-core, com 1, 2, 8 e 16 núcleos de processamento. Onde o aluno motivado
por outros artigos que diziam que poderia haver queda de desempenho com 16 núcleos,
resolveu apresentar um trabalho avaliando o ganho de desempenho conforme se aumen-
tou o número de núcleos de processamento. Nessa simulação, diferentemente do que foi
simulado no artigo base, o aluno não simulou a contenção na memória, que seria gerado,
por exemplo, por conflitos de acesso a um número restrito de portas de acesso. Como
resultado, não houve quedas de desempenho conforme aumentou a quantidade de núcleos
de processamento, levantando a hipótese sobre a influência da contenção de memória, a
qual deve ter grande influência no desempenho final do sistema multi-core.
O segundo ano da disciplina com o Simics foi positivo, entretanto, houve um
contratempo inicial relacionado com as licenças do Simics, uma vez que a Virtutech estava
com algumas mudanças no fornecimento de licenças, houve um atraso inicial para que os
alunos pudessem ter acesso a ferramenta de simulação.
Porém, a exigência logo no inicio do semestre de projetos bem descritos, com
objetivos claros facilitou a execução dos trabalhos pelos alunos, permitindo também uma
maior interação com sugestões e criticas na etapa de proposta, fazendo os alunos pensar
sobre as metas reais e resultados esperados, de maneira a fortalecer também os conceitos
Livro "Arquitetura de Computadores: Educação, Ensino e Aprendizado", 1ed.Porto Alegre: Sociedade Brasileira de Computação, 2012, v. 1, p. 74-110.
ISBN: 9788576692638
Atividades Jan Fev Mar Abr Mai Jun Jul
Pedido de Licenças X
Preparação de Discos Virtuais X X
Introdução à Disciplina X
Apresentação Teórica do Simics X
Definição do Projeto aos Alunos X
Apresentação Prática do Simics X
Data Limite da Entrega dos Projetos X
Apresentação de Andamento dos Trabalhos X X
Apresentação Final dos Trabalhos X
Atividade de Monitoria X X X X X
Tabela 3.1. Cronograma de Atividades
de metodologia científica.
A introdução ao Simics e o suporte dado aos alunos se mostrou mais eficiente
nesse segundo ano. No entanto, percebeu-se a necessidade de introduzir o ambiente de
simulação ainda mais cedo, logo no início da disciplina, mesmo antes do ensino teórico
sobre arquiteturas paralelas. Dessa forma, os alunos terão uma noção mais sólida do
simulador e suas funcionalidades, facilitando a proposta de projetos por parte dos alunos.
O uso de uma única carga de trabalho por todos os alunos não foi suficiente criar
ambiente competitivo entre os alunos, porém, a disponibilização dessas aplicações parale-
las, antes mesmo dos alunos aprenderem conceitos de programação paralela, foi de grande
importância para o bom andamento dos trabalhos. Uma vez que, os alunos puderam testar
suas arquiteturas e apresentar resultados de desempenho durante um seminário de anda-
mento. Com isso os alunos ficaram de certa forma, mais nivelados, evoluindo no projeto
da disciplina de forma mais tranqüila.
Mostramos o cronograma sugerido para a utilização do simulador em sala de aula
na Tabela 3.1. Como pode ser visto no cronograma, existem duas etapas antes mesmo do
início das aulas, que ocorre no mês de Março, essas etapas são planejadas para dar mais
tempo de preparação do ambiente de simulação para os alunos. Depois, podemos ver 6
etapas planejadas para o início das aulas, onde são apresentados aos alunos o ambiente
de simulação e também é sugerido alguns trabalhos, para que os alunos tenham tempo de
propor seus projetos para a disciplina. Então, nas próximas 3 atividades, são marcadas as
datas de entrega e apresentação dos trabalhos. Finalmente, a última atividade listada, de
monitoria, deve ocupar praticamente todos os meses com aulas da disciplina, sendo que
essa e a atividade que faz o acontecer mais facilmente por parte dos alunos, que devem
ser encorajados a procurar a monitoria sempre que estejam com dúvidas.
De um modo geral, a metodologia cumpriu com o esperado. Os alunos projetaram
e desenvolveram uma arquitetura de processador multi-core, simularam esta arquitetura
em um ambiente completo com sistema operacional, rede e programas reais. Além disto,
os alunos, ao final da disciplina conseguiram desenvolver e avaliar um programa paralelo
para a arquitetura proposta.
Livro "Arquitetura de Computadores: Educação, Ensino e Aprendizado", 1ed.Porto Alegre: Sociedade Brasileira de Computação, 2012, v. 1, p. 74-110.
ISBN: 9788576692638
3.8. Conclusões
Os processadores multi-core e many-core, estão se tornando realidade, e representam um
novo paradigma em arquiteturas de computadores, uma vez que esses diversos núcleos
de processamento disponíveis nos atuais e futuros processadores devem tirar proveito do
paralelismo no nível de fluxo de instruções.
Nesse panorama, o ensino de arquiteturas paralelas é de grande importância para
a formação das futuras gerações de cientistas da computação. Esse ensino de arquiteturas
paralelas deve envolver não apenas os núcleos de processamento desses novos proces-
sadores, mas também, todos os dispositivos que vão oferecer suporte adequado para o
funcionamento desses núcleos de processamento.
Visando assim, o ensino de arquiteturas paralelas, esse capítulo apresentou uma
experiência de ensino de novas arquiteturas, auxiliado por um ambiente de simulação
completo.
Podemos observar que o simulador Simics, apresentado nesse capítulo, possui
diversas características positivas, como controle, flexibilidade, parametrização, e demais
funcionalidades que justificam o seu uso em sala de aula, como ferramenta de ensino para
disciplinas de arquitetura paralela.
Através dos dois anos de experiência de utilização desse simulador em sala de
aula, podemos notar a importância do profundo entendimento do funcionamento da fer-
ramenta e do bom planejamento de atividades, para que os alunos possam tirar proveito
de todos os recursos disponíveis em prol do aprendizado.
Entretanto, devemos considerar a adoção de um plano de melhorias contínuas ao
longo dos anos, a fim de aprimorar os materiais didáticos e manuais de uso do simulador,
cronogramas de atividades e planos de ensino. Dessa maneira, podemos fornecer cada vez
mais suporte aos alunos, mudando também o foco para as futuras arquiteturas e pesquisas.
3.9. Agradecimentos
Agradecemos ao CNPq, CAPES e FAPEMIG que contribuíram com o financiamento para
o desenvolvimento deste trabalho.
Referências
[1] UNGERER, T.; ROBIC, B.; SILC, J. A survey of processors with explicit multi-
threading. ACM Computing Surveys, v. 35, n. 1, p. 29–63, 2003.
[2] UNGERER, T.; ROBIC, B.; SILC, J. Multithreaded processors. British Computer
Society, v. 45, n. 3, p. 320–348, 2002.
[3] HENNESSY, J. L.; PATTERSON, D. A. Computer Architecture: A Quantitative Ap-
proach. Fourth. USA: Elsevier, Inc., 2007.
[4] SMITH, J. E.; SOHI, G. S. The microarchitecture of superscalar processors. IEEE,
v. 83, n. 12, p. 1609–1624, 1995.
Livro "Arquitetura de Computadores: Educação, Ensino e Aprendizado", 1ed.Porto Alegre: Sociedade Brasileira de Computação, 2012, v. 1, p. 74-110.
ISBN: 9788576692638
[5] STALLINGS, W. Computer Organization and Architecture: Designing for Perfor-
mance. Fourth. USA: Prentice Hall, 1996.
[6] OLUKOTUN, K. et al. The case for a single-chip multiprocessor. In: Proceedings
ASPLOS: Int. Symp. on Architectural Support for Programming Languages and Oper-
ating Systems. [S.l.]: IEEE, 1996. p. 2–11.
[7] SINHAROY, B. et al. Power5 system microarchitecture. IBM Journal of Research
and Development, v. 49, n. 4/5, 2005.
[8] BARROSO, L. A. et al. Piranha: a scalable architecture based on single-chip multi-
processing. In: Proceedings ISCA: Int. Symp. on Computer Architecture. [S.l.]: IEEE,
2000. p. 282–293.
[9] KONGETIRA, P.; AINGARAN, K.; OLUKOTUN, K. Niagara: a 32-way multi-
threaded sparc processor. IEEE Micro, v. 25, n. 2, p. 21–29, 2005.
[10] KUMAR, R. et al. Heterogeneous chip multiprocessors. IEEE Computer, v. 38,
n. 11, p. 32–38, 2005.
[11] FREITAS, H. C.; NAVAUX, P. O. A. Chip Multithreading: Conceitos, Arquite-
turas e Tendências. Dissertação (Trabalho Individual) — Universidade Federal do Rio
Grande do Sul, Porto Alegre, Brasil, 2006.
[12] SPRACKLEN, L.; ABRAHAM, S. Chip multithreading: Opportunities and chal-
lenges. In: Proceedings HPCA: Int. Symp. on High-Performance Computer Architec-
ture. [S.l.]: IEEE, 2005. p. 248–252.
[13] ACOSTA, C. et al. A complexity-effectivesimultaneous multithreading architecture.
In: Proceedings Int. Conf. on Parallel Processing. [S.l.: s.n.], 2005. p. 157–164. ISSN
0190-3918.
[14] KOUFATY, D.; MARR, D. T. Hyperthreading technology in the netburst microar-
chitecture. IEEE Micro, v. 23, n. 2, p. 56–65, 2003.
[15] GONÇALVEZ, R.; NAVAUX, P. O. A. Improving smt performance scheduling pro-
cesses. In: Proceedings Euromicro, Workshop on Parallel, Distributed and Network-
based Processing. [S.l.: s.n.], 2002. p. 327–334.
[16] EGGERS, S. J. et al. Simultaneous multithreading: A platform for next generation
processors. IEEE Micro, p. 12–19, 1997.
[17] HAMMOND, L. et al. The stanford hydra cmp. IEEE Micro, IEEE Computer Soci-
ety Press, Los Alamitos, CA, USA, v. 20, n. 2, p. 71–84, 2000. ISSN 0272-1732.
[18] KUMAR, R. et al. Single-isa heterogeneous multi-core architectures for multi-
threaded workload performance. In: Proceedings SIGARCH Comput. Archit. News.
New York, NY, USA: ACM, 2004. v. 32, n. 2, p. 64. ISSN 0163-5964.
[19] WOLF, W. The future of multiprocessor system on chip. In: Proceedings DAC:
Design Automation Conf. [S.l.: s.n.], 2004.
Livro "Arquitetura de Computadores: Educação, Ensino e Aprendizado", 1ed.Porto Alegre: Sociedade Brasileira de Computação, 2012, v. 1, p. 74-110.
ISBN: 9788576692638
[20] ROSE, C. A. F. D.; NAVAUX, P. O. A. Arquiteturas Paralelas. Porto Alegre RS,
Brasil: Editora Sagra Luzzatto, 2003.
[21] CULLER, D. E.; SINGH, J. P. Parallel Computer Architecture: A Hard-
ware/Software Approach. San Francisco, USA: Morgan Kaufmann, 1999.
[22] PATTERSON, D. A.; HENNESSY, J. L. Organização e projeto de computadores.
Second. Rio de Janeiro, Brasil: Editora Campus, 2005.
[23] BJERREGAARD, T.; MAHADEVAN, S. A survey of research and practices of
network-on-chip. ACM Computing Surveys, v. 38, p. 1–51, 2006.
[24] JAIN, R. The art of computer systems performance analysis: techniques for exper-
imental design, measurement, simulation, and modeling. New York, USA: J. Wiley,
1991.
[25] JOHN, L. K.; EECKHOUT, L. Performance Evaluation and Benchmarking. Boca
Raton, USA: Taylor & Francis Group, 2006.
[26] MAGNUSSON, P. et al. Simics: A full system simulation platform. IEEE Computer
Micro, v. 35, n. 2, p. 50–58, Feb 2002. ISSN 0018-9162.
[27] SIMONG. Inaccurate Simulation. Simics Forum, 2007. Disponível em:
<https://www.simics.net/mwf/topic_show.pl?pid=55029>. Acesso em: agosto 2008.
Disponível em: <https://www.simics.net/mwf/topic_show.pl?pid=55029>.
[28] VIRTUTECH SIMICS. Simics 3.0 – User Guide for Unix. [s.n.], 2007.
Disponível em: <http://www.simics.net>. Acesso em: junho 2008. Disponível em:
<http://www.simics.net>.
[29] THOZIYOOR, S. et al. A comprehensive memory modeling tool and its application
to the design and analysis of future memory hierarchies. In: Proceedings ISCA: Int.
Symp. on Computer Architecture. [S.l.: s.n.], 2008. p. 51–62.
[30] ALAMELDEEN, A. R. et al. Evaluating non-deterministic multi-threaded commer-
cial workloads. Computer Architecture Evaluation using Comercial Workloads, 2002.
[31] ALAMELDEEN, A. R.; WOOD, D. A. Variability in architectural simulations of
multi-threaded workloads. In: Proceedings HPCA: Int. Symp. on High-Performance
Computer Architecture. [S.l.: s.n.], 2003. p. 7–18.
Livro "Arquitetura de Computadores: Educação, Ensino e Aprendizado", 1ed.Porto Alegre: Sociedade Brasileira de Computação, 2012, v. 1, p. 74-110.
ISBN: 9788576692638