Atenção: Este exercício, assim como todos os demais, é individual. Isto significa que você não pode, em hipótese alguma, olhar o código de um de seus colegas. Você pode tirar dúvidas longe do computador ou pedir auxílio ao professor.
Você deve relembrar os conceitos relacionados à medidas de desempenho. Procure pensar em respostas para as seguintes perguntas (não precisa colocá-las no seu relatório):
É importante que você saiba responder estas perguntas antes de continuar a atividade.
Nesta atividade, assim como em várias outras da disciplina, utilizaremos um simulador do processador MIPS, feito na linguagem ArchC. Durante o semestre você irá aprender mais sobre esta linguagem e a capacidade de implementar simuladores distintos. Mas neste primeiro momento, o importante é entender as noções básicas do simulador, como invocá-lo, como compilar programas e como gerar um resultado correto de execução.
ArchC é uma linguagem para descrição de arquiteturas de processadores. A finalidade principal é facilitar o trabalho do projetista de processadores e também de sistemas, acelerando o desenvolvimento de simuladores e demais ferramentas necessárias para a avaliação de uma ideia, antes de passar para a fase de prototipação em hardware.
Todos os arquivos que você vai precisar utilizar neste exercício estão disponíveis no meu homedir do IC3, em /home/staff/rodolfo/mc723. Na pasta download existem versões prontas para descompactar e instalar.
Vamos utilizar o modelo do processador MIPS, que é uma versão ampliada do processador estudado na disciplina MC722, com instruções extras. O modelo está disponível na pasta download (mips1-v0.7.8.tgz). Descompacte este arquivo e leia o README que o acompanha. Nele há instruções específicas sobre a copmilação do simulador do processador. Para isto, você vai precisar do gerador de simuladores acsim, que já está instalado em /home/staff/rodolfo/mc723/archc/bin/acsim (adicione ao PATH para facilitar os usos futuros). Três comandos são necessários:
acsim mips1.ac -abi
make -f Makefile.archc
mips1.x --load=[args]
O primeiro comando cria os arquivos do simulador, baseados na descrição contida em mips1.ac (arquivo principal de descrição do processador em ArchC). O segundo comando compila o simulador, gerando um executável chamado mips1.x. O terceiro comando é a utilização do simulador para executar um programa compilado para MIPS. Como não temos nenhum programa para MIPS, crie um arquivo chamado hello.c com o clássico "Hello World" e vamos compilá-lo.
Devido às características da instalação do IC-3, somente a máquina xaveco tem o compilador para MIPS instalado. Assim, sempre que precisar compilar um programa para MIPS, você deve executar os comandos na máquina xaveco. Adicione o caminho /l/archc/compilers/bin no seu PATH também.
mips-elf-gcc -specs=archc hello.c -o hello.mips
De forma similar ao gcc que você está acostumado a utilizar, esta é uma versão do gcc compilada para gerar binários para a arquitetura MIPS. Todas as demais ferramentas de desenvolvimento também existem numa versão com o prefixo mips-elf. Denomina-se cross-compiler um compilador que roda numa plataforma (x86 no caso) e gera programas para executar em outra (MIPS no nosso exemplo). O parâmetro -specs=archc informa algumas regras específicas do ArchC, que devem ser seguidas pelo compilador. Os últimos parâmetros indicam o arquivo a ser gerado e estamos gerando o programa com o sufixo da arquitetura para facilitar o entendimento. De posse do novo executável, agora basta invocar o simulador e ver seu programa sendo executado.
mips1.x --load=hello.mips
Uma outra ferramenta que pode ser útil é o objdump (na forma mips-elf-objdump para MIPS). Ele é capaz de mostrar várias informações sobre o programa (consulte o manual para ver as opções). Um exemplo de uso para listar o código assembly é:
mips-elf-objdump -d hello.mips
Reconheceu alguma instrução? Conseguiu entender um pouco do código?
As instruções implementadas pelo simulador estão descritas em dois arquivos: mips1_isa.ac e mips1_isa.cpp. O primeiro descreve quais instruções o processador terá e a codificação delas. O segundo arquivo contém uma implementação do comportamento da instrução (um trecho de código em C++ que descreve a funcionalidade da instrução). Abra o segundo arquivo e procure por ac_behavior( add ), este trecho de código parece intuitivo?
Agora que você já sabe gerar o simulador, a primeira tarefa é contar quantas vezes a instrução add acontece durante a execução do seu "Hello World". Para isto, você deverá editar o arquivo mips_isa.cpp e incluir um contador global. Você pode editar o ac_behavior(add) e também deve precisar editar os ac_behavior(begin) e ac_behavior(end) que são executados no início e final da simulação, respectivamente. Recompile o simulador e execute seu programa. Os resultados sairam como você esperava? Caso não tenha havido nenhuma instrução add, você consegue modificar o código fonte do programa para que apareça ao menos uma? Dica: utilize o objdump para tentar entender o que está acontecendo.
Como cada instrução tem um trecho diferente de código em C++ para implementa-la, o tempo de simulação não está relacionado diretamente com o tempo de execução de um programa. Por isto, ao invés de medirmos o tempo de execução do simulador, vamos computar o tempo em ciclos para a execução do programa. A tabela abaixo indica o CPI médio das categorias de instruções:
Categoria | CPI médio |
---|---|
Acesso à memória | 10 |
Multiplicação e Divisão | 20 |
Outras | 1 |
Ao invés de ter que alterar todo o código do simulador, o acsim possui a opção -s para gerar estatísticas de simulação. Uma das estatísticas é a contagem do número de vezes que cada instrução executou. Regere o seu simulador com esta opção, colete as estatísticas, e calcule quantos ciclos foram gastos para executar seu programa.
Execute 3 programas da tabela abaixo, um de cada coluna, e indique o número de ciclos necessários para executar cada um deles. Os programas são retirados do pacote de benchmark MiBench, que já está compilado e pronto para ser descompactado no meu homedir do IC-3. Utilize os 3 últimos dígitos do seu RA (quarto, quinto e sexto) para selecionar o programa.
Dígito do RA | quarto | quinto | sexto |
---|---|---|---|
(small) | (small) | (large) | |
0 | basicmath | stringsearch | susan corners |
1 | qsort | rijndael coder | jpeg coder |
2 | susan corners | rijndael decoder | dijkstra |
3 | susan edges | sha | patricia |
4 | susan smoothing | adpcm encoder | gsm coder |
5 | jpeg coder | adpcm decoder | rijndael coder |
6 | jpeg decoder | crc32 | gsm coder |
7 | lame | fft | adpcm encoder |
8 | dijkstra | gsm coder | sha |
9 | patricia | gsm decoder | stringsearch |
Veja instruções detalhadas sobre a execução e a conferência dos resultados dos programas no arquivo README dentro da pasta de cada um dos programas.
Todos devem entregar um relatório de 1 qpágina, no formato PDF, através do Susy. Guardem o código fonte até o final do semestre.