Simuladores de sistemas computacionais: o já familiar simulador multiplataforma e os desconhecidos potáquicos e trilhas

Na segunda parte do artigo sobre simuladores de sistemas computacionais, continuarei a discutir de forma simples e informativa sobre simuladores de computador, especificamente sobre simulação de plataforma completa, que é mais frequentemente enfrentada pelo usuário comum, bem como sobre modelos de ciclo e trilhas que são mais comuns entre desenvolvedores.

Simuladores de sistemas computacionais: o já familiar simulador multiplataforma e os desconhecidos potáquicos e trilhas

Em primeira parte Já expliquei o que são simuladores de forma geral, além dos níveis de modelagem. Agora, com base nesse conhecimento, proponho mergulhar um pouco mais fundo e conversar sobre simulação de plataforma completa, como montar trilhas, o que fazer com elas depois, bem como sobre emulação de microarquitetura de ciclo.

Simulador de plataforma completa (full platform simulator), ou "Um homem só não é guerreiro".

Se for necessário investigar o funcionamento de um dispositivo específico, como uma placa de rede, ou escrever firmware ou driver para esse dispositivo, pode-se simular esse dispositivo separadamente. No entanto, usá-lo isoladamente da infraestrutura restante não é muito conveniente. Para executar o driver correspondente, são necessários o processador central, a memória, acesso ao barramento para transferência de dados, entre outros. Além disso, para o funcionamento do driver, são necessárias um sistema operacional (SO) e uma pilha de rede. Pode ser necessário também um gerador de pacotes separado e um servidor para receber respostas.

O simulador de plataforma completa cria um ambiente para executar toda a pilha de software, que abrange tudo, desde o BIOS e o carregador até o próprio sistema operacional e suas várias subsistemas, como a pilha de rede, drivers e aplicações de nível de usuário. Para isso, ele implementa modelos de software da maioria dos dispositivos do computador: processador e memória, disco, dispositivos de entrada e saída (teclado, mouse, monitor), além da mencionada placa de rede.

Abaixo está o diagrama de blocos do chipset x58 da Intel. Em um simulador de computador de plataforma completa com este chipset, é necessário implementar a maioria dos dispositivos listados, incluindo aqueles que estão dentro do IOH (Input/Output Hub) e ICH (Input/Output Controller Hub), que não estão desenhados detalhadamente no diagrama de blocos. No entanto, como mostra a prática, há muitos dispositivos que não são utilizados pelo software que pretendemos executar. Modelos desses dispositivos podem não ser criados.

Simuladores de sistemas computacionais: o já familiar simulador multiplataforma e os desconhecidos potáquicos e trilhas

Na maioria das vezes, simuladores de plataforma completa são implementados no nível de instruções do processador (ISA, veja artigo anterior). Isso permite criar o 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 do nível API/ABI, que muda com mais frequência. Além disso, a implementação no nível de instruções permite executar o que é chamado de software binário não modificado, ou seja, executar código já compilado sem quaisquer modificações, exatamente da maneira como é usado no hardware real. Em outras palavras, pode-se fazer uma cópia ("dump") do disco rígido, especificá-lo como imagem para o modelo no simulador de plataforma completa e - voilà! - o sistema operacional e outros programas são carregados no simulador sem quaisquer ações adicionais.

Desempenho dos simuladores

Simuladores de sistemas computacionais: o já familiar simulador multiplataforma e os desconhecidos potáquicos e trilhas

Como mencionado anteriormente, o próprio processo de simulação de todo o sistema, ou seja, de todos os seus dispositivos, é um empreendimento bastante demorado. Mesmo se realizarmos tudo isso em um nível muito detalhado, como no microarquitetura ou lógico, a execução se tornará extremamente lenta. O nível de instruções é uma escolha adequada e permite que o sistema operacional e os programas sejam executados em velocidades suficientes para que o usuário tenha uma interação confortável com eles.

Aqui é apropriado tocar no tópico de desempenho dos simuladores. Normalmente, é 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 em que a simulação está sendo executada. Portanto, talvez seja mais correto falar sobre "desaceleração" (slowdown) do simulador em comparação com o sistema original.

Os simuladores de plataforma completa mais comuns no mercado, como QEMU, VirtualBox ou VmWare Workstation, têm um bom desempenho. Para o usuário, pode até não ser perceptível que o trabalho está ocorrendo em um simulador. Isso acontece graças à funcionalidade especial de virtualização implementada nos processadores, aos algoritmos de tradução binária e a outras questões interessantes. Tudo isso é um tema para um artigo separado, mas, resumidamente, a virtualização é uma capacidade de hardware dos processadores modernos que permite que os simuladores não simulem instruções, mas executem-nas diretamente no procesador real, desde que, claro, as arquiteturas do simulador e do processador sejam semelhantes. A tradução binária é a conversão do código de máquina convidado para o código de máquina hospedeiro e sua execução subsequente no 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 que o sistema real. Embora isso dependa de 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 Simics, nas versões mais recentes, suportam hardware de hospedagem multiprocessador e paralelizam de forma eficaz os núcleos simulados com os núcleos do processador real.

Falando sobre a velocidade da simulação microarquitetural, isso geralmente ocorre em ordens de magnitude inferiores, cerca de 1000 a 10000 vezes mais lento na execução em um computador comum, sem simulação. E as implementações no nível de elementos lógicos são ainda mais lentas. Portanto, em nível de emulação, utilizam-se FPGA, o que permite aumentar significativamente o desempenho.

O gráfico abaixo mostra a dependência aproximada da velocidade de simulação em relação ao detalhamento do modelo.

Simuladores de sistemas computacionais: o já familiar simulador multiplataforma e os desconhecidos potáquicos e trilhas

Simulação de ciclo

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. Aqui pode surgir um mal-entendido – afinal, por que não programar o tempo de execução de cada instrução? No entanto, um simulador assim funcionaria de maneira muito imprecisa, pois o tempo de execução da mesma instrução pode variar de chamada para chamada.

Um exemplo simples é a instrução de acesso à memória. Se a célula de memória solicitada estiver disponível no cache, o tempo de execução será mínimo. Se a informação não estiver no cache (um ‘cache miss’), isso aumentará significativamente o tempo de execução da instrução. Portanto, para simulação precisa, é necessário um modelo de cache. No entanto, o modelo de cache não é tudo. O processador não aguardará passivamente a obtenção dos dados da memória caso eles não estejam no cache. Em vez disso, ele começará a executar as próximas instruções, escolhendo aquelas que não dependem do resultado da leitura da memória. Isso é chamado de execução fora de ordem (OOO, out of order execution), necessário para minimizar o tempo de inatividade do processador. Considerar tudo isso ao calcular o tempo de execução das instruções ajudará a modelar os blocos correspondentes do processador. Entre essas instruções que são executadas enquanto se aguarda o resultado da leitura da memória, pode haver uma operação de desvio condicional. Se o resultado da condição não for conhecido no momento, o processador não interrompe a execução, mas faz uma ‘suposição’, realiza o desvio correspondente e continua a executar preventivamente as instruções a partir do ponto de desvio. Esse bloco, chamado de predictor de desvios, também deve ser implementado em um simulador microarquitetural.

A imagem abaixo mostra os principais blocos do processador; não é necessário conhecê-los, mas eles são apresentados apenas para ilustrar a complexidade da implementação microarquitetural.

Simuladores de sistemas computacionais: o já familiar simulador multiplataforma e os desconhecidos potáquicos e trilhas

O funcionamento de todos esses blocos em um processador real é sincronizado por sinais de clock especiais, de forma semelhante ao que ocorre no modelo. Esse tipo de simulador de microarquitetura é chamado de simulador por ciclos (cycle accurate). Seu principal objetivo é prever com precisão o desempenho do processador em desenvolvimento e/ou calcular o tempo de execução de um programa específico, como um benchmark. Se os valores forem inferiores ao necessário, será preciso revisar os algoritmos e os blocos do processador ou otimizar o programa.

Como mostrado acima, a simulação por ciclos é muito lenta, portanto, é utilizada apenas na pesquisa de determinados aspectos do funcionamento do programa, onde é necessário descobrir a velocidade real de execução e avaliar o desempenho futuro do dispositivo cujo protótipo está sendo modelado.

Para simular o restante do tempo de execução do programa, usa-se um simulador funcional. Como ocorre essa utilização combinada na prática? Primeiro, inicia-se o simulador funcional, onde o sistema operacional e tudo o que é necessário para executar o programa em estudo são carregados. Afinal, não estamos interessados nem no próprio sistema operacional, nem nas etapas iniciais de inicialização do programa, sua configuração, etc. Porém, também não podemos ignorar essas partes e partir diretamente para a execução do programa a partir do meio. Portanto, todas essas etapas preliminares são executadas no simulador funcional. Depois que o programa é executado até o ponto de interesse, existem duas opções. Podemos substituir o modelo pelo simulador por ciclos e continuar a execução. O modo de simulação que utiliza o código executável (ou seja, arquivos de programas compilados normais) é chamado de simulação por execução (execution driven simulation). Esta é a forma mais comum de simulação. Existe também outra abordagem – a simulação baseada em trilhas (trace driven simulation).

Simulação baseada em trilhas

Consiste em duas etapas. Utilizando um simulador funcional ou em um sistema real, registra-se e grava-se em um arquivo o log das ações do programa. Esse log é chamado de trilha (trace). Dependendo do que está sendo pesquisado, a trilha pode incluir instruções executáveis, endereços de memória, números de portas e informações sobre interrupções.

O próximo passo é o "replay" da trilha, quando o simulador por ciclo lê a trilha e executa todas as instruções nela gravadas. No final, obtemos o tempo de execução deste trecho de programa, além de várias características desse processo, como a porcentagem de acertos no cache.

Uma característica importante do trabalho com trilhas é a determinabilidade, ou seja, ao executar a simulação da maneira descrita acima, repetidamente reproduzimos a mesma sequência de ações. Isso permite, ao alterar os parâmetros do modelo (tamanhos do cache, buffers e filas) e usando diferentes algoritmos internos ou ajustando-os, investigar como cada parâmetro influencia o desempenho do sistema e qual opção oferece os melhores resultados. Tudo isso pode ser feito com o modelo do protótipo do dispositivo antes da criação do protótipo de hardware real.

A complexidade dessa abordagem reside na necessidade de preparação prévia do aplicativo e coleta da trilha, além do enorme tamanho do arquivo da trilha. Entre os pontos positivos, está o fato de que é suficiente modelar apenas a parte do dispositivo ou plataforma de interesse, enquanto a simulação por execução geralmente requer um modelo completo.

Assim, neste artigo, examinamos as características da simulação de plataforma completa, discutimos a velocidade de implementações em diferentes níveis, simulação por ciclo e trilhas. No próximo artigo, descreverei os principais cenários de uso dos simuladores, tanto para fins pessoais quanto do ponto de vista do desenvolvimento em grandes empresas.

Fonte: habr.com

Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS 🔥 Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS | ProHoster