Simuladores de sistemas computacionais: um simulador familiar de plataforma completa e sentido horário e traços desconhecidos

Na segunda parte do artigo sobre simuladores de sistemas informáticos, continuarei a falar de uma forma introdutória simples sobre simuladores de computador, nomeadamente sobre a simulação de plataforma completa, que o utilizador médio encontra com mais frequência, bem como sobre o clock-by -modelo de relógio e rastreamentos, que são mais comuns nos círculos de desenvolvedores.

Simuladores de sistemas computacionais: um simulador familiar de plataforma completa e sentido horário e traços desconhecidos

В a primeira parte Falei sobre o que são simuladores em geral, bem como sobre os níveis de simulação. Agora, com base nesse conhecimento, proponho mergulhar um pouco mais fundo e falar sobre simulação de plataforma completa, como coletar traços, o que fazer com eles depois, bem como sobre emulação de microarquitetura relógio a relógio.

Simulador de plataforma completo, ou “Sozinho no campo não é guerreiro”

Se você deseja estudar a operação de um dispositivo específico, por exemplo, uma placa de rede, ou escrever firmware ou driver para este dispositivo, esse dispositivo pode ser simulado separadamente. Porém, utilizá-lo isoladamente do restante da infraestrutura não é muito conveniente. Para executar o driver correspondente, você precisará de um processador central, memória, acesso a um barramento de dados, etc. Além disso, o driver requer um sistema operacional (SO) e uma pilha de rede para funcionar. Além disso, um gerador de pacotes e um servidor de resposta separados podem ser necessários.

Um simulador de plataforma completa cria um ambiente para executar uma pilha de software completa, que inclui tudo, desde o BIOS e o carregador de inicialização até o próprio sistema operacional e seus vários subsistemas, como a mesma pilha de rede, drivers e aplicativos de nível de usuário. Para isso, implementa modelos de software da maioria dos dispositivos de computador: processador e memória, disco, dispositivos de entrada/saída (teclado, mouse, display), bem como a mesma placa de rede.

Abaixo está um diagrama de blocos do chipset x58 da Intel. Um simulador de computador de plataforma completa neste chipset requer a implementação da maioria dos dispositivos listados, incluindo aqueles dentro do IOH (Input/Output Hub) e ICH (Input/Output Controller Hub), que não são descritos em detalhes no diagrama de blocos. . Embora, como mostra a prática, não existam muitos dispositivos que não sejam utilizados pelo software que vamos executar. Não é necessário criar modelos de tais dispositivos.

Simuladores de sistemas computacionais: um simulador familiar de plataforma completa e sentido horário e traços desconhecidos

Na maioria das vezes, os simuladores de plataforma completa são implementados no nível de instrução do processador (ISA, veja abaixo). artigo anterior). Isso permite que você crie o próprio simulador de forma relativamente rápida e econômica. O nível ISA também é bom porque permanece mais ou menos constante, ao contrário, por exemplo, do nível API/ABI, que muda com mais frequência. Além disso, a implementação no nível da instrução permite executar o chamado software binário não modificado, ou seja, executar o código já compilado sem nenhuma alteração, exatamente como é usado no hardware real. Em outras palavras, você pode fazer uma cópia (“dump”) do seu disco rígido, especificá-lo como uma imagem para um modelo em um simulador de plataforma completa e pronto! – O sistema operacional e outros programas são carregados no simulador sem quaisquer ações adicionais.

Desempenho do simulador

Simuladores de sistemas computacionais: um simulador familiar de plataforma completa e sentido horário e traços desconhecidos

Como foi mencionado acima, o processo de simulação de todo o sistema, ou seja, todos os seus dispositivos, é uma tarefa bastante lenta. Se você também implementar tudo isso em um nível muito detalhado, por exemplo, microarquitetural ou lógico, a execução se tornará extremamente lenta. Mas o nível de instrução é uma escolha apropriada e permite que o sistema operacional e os programas sejam executados em velocidades suficientes para que o usuário interaja com eles confortavelmente.

Aqui seria apropriado abordar o tema do desempenho do simulador. Geralmente é medido em IPS (instruções por segundo), mais precisamente em MIPS (milhões de IPS), ou seja, o número de instruções do processador executadas pelo simulador em um segundo. Ao mesmo tempo, a velocidade da simulação também depende do desempenho do sistema no qual a simulação é executada. Portanto, talvez seja mais correto falar da “desaceleração” do simulador em relação ao sistema original.

Os simuladores de plataforma completa mais comuns do mercado, como QEMU, VirtualBox ou VmWare Workstation, apresentam bom desempenho. Pode nem ser perceptível para o usuário que o trabalho está acontecendo no simulador. Isso acontece graças aos recursos especiais de virtualização implementados em processadores, algoritmos de tradução binária e outras coisas interessantes. Tudo isso é assunto para um artigo à parte, mas resumindo, a virtualização é um recurso de hardware dos processadores modernos que permite aos simuladores não simular instruções, mas enviá-las para execução diretamente a um processador real, a menos, é claro, que as arquiteturas de o simulador e o processador são semelhantes. A tradução binária é a tradução do código da máquina convidada em código host e subsequente execução em um processador real. Como resultado, a simulação é apenas um pouco mais lenta, de 5 a 10 vezes, e muitas vezes até funciona na mesma velocidade do sistema real. Embora isso seja influenciado por muitos fatores. Por exemplo, se quisermos simular um sistema com várias dezenas de processadores, a velocidade cairá imediatamente várias dezenas de vezes. Por outro lado, simuladores como o Simics nas versões mais recentes suportam hardware host multiprocessador e paralelizam efetivamente os núcleos simulados nos núcleos de um processador real.

Se falamos sobre a velocidade da simulação microarquitetural, geralmente ela é de várias ordens de magnitude, cerca de 1000 a 10000 vezes mais lenta do que a execução em um computador normal, sem simulação. E as implementações no nível dos elementos lógicos são mais lentas em várias ordens de grandeza. Portanto, um FPGA é usado como emulador nesse nível, o que pode aumentar significativamente o desempenho.

O gráfico abaixo mostra uma dependência aproximada da velocidade de simulação nos detalhes do modelo.

Simuladores de sistemas computacionais: um simulador familiar de plataforma completa e sentido horário e traços desconhecidos

Simulação batida por batida

Apesar da baixa velocidade de execução, os simuladores microarquiteturais são bastante comuns. A simulação dos blocos internos do processador é necessária para simular com precisão o tempo de execução de cada instrução. Podem surgir mal-entendidos aqui - afinal, ao que parece, por que não simplesmente programar o tempo de execução para cada instrução. Mas tal simulador será muito impreciso, pois o tempo de execução da mesma instrução pode diferir de chamada para chamada.

O exemplo mais simples é uma instrução de acesso à memória. Se o local de memória solicitado estiver disponível no cache, o tempo de execução será mínimo. Se esta informação não estiver no cache (“cache miss”), isso aumentará bastante o tempo de execução da instrução. Assim, um modelo de cache é necessário para uma simulação precisa. Contudo, a questão não se limita ao modelo de cache. O processador não irá simplesmente esperar que os dados sejam recuperados da memória quando eles não estiverem no cache. Em vez disso, começará a executar as próximas instruções, escolhendo aquelas que não dependem do resultado da leitura da memória. Esta é a chamada execução “fora de ordem” (OOO, execução fora de ordem), necessária para minimizar o tempo ocioso do processador. A modelagem dos blocos de processador correspondentes ajudará a levar tudo isso em consideração no cálculo do tempo de execução das instruções. Dentre essas instruções, executadas enquanto se aguarda o resultado da leitura da memória, pode ocorrer uma operação de salto condicional. Se o resultado da condição for desconhecido no momento, então novamente o processador não interrompe a execução, mas faz uma “adivinhação”, executa a ramificação apropriada e continua a executar proativamente as instruções a partir do ponto de transição. Tal bloco, denominado preditor de ramificação, também deve ser implementado no simulador microarquitetural.

A figura abaixo mostra os principais blocos do processador, não é necessário conhecê-la, é mostrada apenas para mostrar a complexidade da implementação da microarquitetura.

Simuladores de sistemas computacionais: um simulador familiar de plataforma completa e sentido horário e traços desconhecidos

A operação de todos esses blocos em um processador real é sincronizada por sinais de clock especiais, e o mesmo acontece no modelo. Esse simulador microarquitetural é chamado de precisão de ciclo. Seu principal objetivo é prever com precisão o desempenho do processador que está sendo desenvolvido e/ou calcular o tempo de execução de um programa específico, por exemplo, um benchmark. Caso os valores sejam inferiores aos exigidos, será necessário modificar os algoritmos e blocos do processador ou otimizar o programa.

Conforme mostrado acima, a simulação relógio a relógio é muito lenta, por isso é utilizada apenas no estudo de determinados momentos de funcionamento de um programa, onde é necessário saber a velocidade real de execução do programa e avaliar o desempenho futuro do dispositivo cujo protótipo está sendo simulado.

Neste caso, um simulador funcional é utilizado para simular o tempo restante de execução do programa. Como essa combinação de uso acontece na realidade? Primeiramente é lançado o simulador funcional, no qual são carregados o SO e tudo o que é necessário para executar o programa em estudo. Afinal, não estamos interessados ​​no SO em si, nem nos estágios iniciais de lançamento do programa, sua configuração, etc. No entanto, também não podemos pular essas partes e passar imediatamente para a execução do programa a partir do meio. Portanto, todas essas etapas preliminares são executadas em um simulador funcional. Após a execução do programa até o momento que nos interessa, duas opções são possíveis. Você pode substituir o modelo por um modelo relógio por ciclo e continuar a execução. O modo de simulação que usa código executável (ou seja, arquivos de programa compilados regularmente) é chamado de simulação orientada à execução. Esta é a opção de simulação mais comum. Outra abordagem também é possível – simulação orientada por rastreamento.

Simulação baseada em rastreamento

Consiste em duas etapas. Usando um simulador funcional ou em um sistema real, um log de ações do programa é coletado e gravado em um arquivo. Esse log é chamado de rastreamento. Dependendo do que está sendo examinado, o rastreamento pode incluir instruções executáveis, endereços de memória, números de porta e informações de interrupção.

O próximo passo é “reproduzir” o trace, quando o simulador relógio a relógio lê o trace e executa todas as instruções escritas nele. Ao final, obtemos o tempo de execução desta parte do programa, bem como diversas características desse processo, por exemplo, a porcentagem de acertos no cache.

Uma característica importante do trabalho com traços é o determinismo, ou seja, ao executar a simulação da maneira descrita acima, reproduzimos repetidamente a mesma sequência de ações. Isso permite, alterando os parâmetros do modelo (tamanho de cache, buffer e fila) e utilizando diferentes algoritmos internos ou ajustando-os, estudar como um determinado parâmetro afeta o desempenho do sistema e qual opção dá os melhores resultados. Tudo isso pode ser feito com um modelo de dispositivo protótipo antes de criar um protótipo de hardware real.

A complexidade dessa abordagem reside na necessidade de primeiro executar o aplicativo e coletar o rastreamento, bem como no enorme tamanho do arquivo de rastreamento. As vantagens incluem o fato de bastar simular apenas a parte do dispositivo ou plataforma de interesse, enquanto a simulação por execução geralmente requer um modelo completo.

Portanto, neste artigo examinamos os recursos da simulação de plataforma completa, falamos sobre a velocidade das implementações em diferentes níveis, simulação relógio por ciclo e rastreamentos. No próximo artigo descreverei os principais cenários de utilização de simuladores, tanto para fins pessoais quanto do ponto de vista de desenvolvimento em grandes empresas.

Fonte: habr.com

Adicionar um comentário