• Nenhum resultado encontrado

Conforme descrito na Seção 3.5, o objetivo do monitor de desempenho é acompanhar a execução de um processo, obtendo componentes decompostos do CPI que refletem o comportamento de tal processo. Entre esses compo- nentes, o cpi_comp_base consiste na quantidade de ciclos efetivos para a com- putação realizada até o momento de sua leitura do monitor, enquanto que os demais componentes refletem os ciclos ocupados com eventos de faltas nas memórias internas ou latência de processamento.

A construção de um monitor desempenho cuja saída consiste na CPI stack não é uma tarefa simples, já que exige intenso monitoramento do pipeline do processador e demais componentes para alcançar uma decomposição mais próxima do real. Um dos principais problemas envolvidos nessa atividade é o tratamento do ILP (Instruction Level Paralelism) e do MLP (Memory Level Para- lelism). Essas características estão presentes em processadores e compilado- res, os quais, por meio de reorganização da ordem de execução de instruções, mascaram as latências causadas por elas. Em processadores superescala- res com processamento out-of-order, a tarefa de monitoramento é ainda mais complexa (Eyerman & Eeckhout, 2009) (Koufaty et al., 2010).

É importante considerar que existem diferentes tipos de monitores de de- sempenho, muitos implementados em processadores comerciais. No entanto,

a maioria não possui como saída, o CPI stack, o qual é o principal requisito da heurística deste projeto. Dentro desse contexto, considerando que a im- plementação desses monitores para arquiteturas superscalares out-of-order é complexa e retorna resultados imprecisos de acordo com Allam et al. (2012), este projeto propõe a implementação de um monitor de desempenho apropri- ado para arquiteturas de processadores cuja execução é in-order.

Considerando que não há reordenação de instruções pelo processador, a principal abordagem adotada por este monitor consiste em realizar uma con- tagem do tempo de execução de cada instrução. Porém, assim como abor- dado na Seção 3.5, para uma medida mais precisa, é necessário que existam interfaces com outros componentes do processador. Essas interfaces estão ilustradas na Figura 4.3.

Figura 4.3: Interfaces do monitor de desempenho

O monitor de desempenho deve receber do processador a instrução cor- rente do estágio de execução de seu pipeline. Isso se deve ao fato que nesse estágio, a decisão tomada um ciclo antes pode invalidar automaticamente a instrução no ciclo corrente, no caso da execução de uma branch. Diferente de outros estágios, como por exemplo o estágio de fetch, em que terá a nova instrução independente do branch na instrução anterior ser efetivado. Parale- lamente, os componentes D-TLB, I-TLB, D-CACHE e I-CACHE devem enviar ao monitor um sinal que identifica o período da execução afetada por uma falta ocorrida. A Figura 4.4 ilustra um exemplo hipotético contendo a interface

com esses componentes, ilustrando também como deve ser o comportamento do monitor para a decomposição de três componentes: cpi_comp_dtlb_stall, cpi_comp_dcache_stall e cpi_comp_load_store_stall. O sinal CLK consiste no relógio principal do processador. O sinal start é externo ao bloco de monitora- mento, provindo de alguma interface com o barramento principal. Esse sinal indica o momento em que o monitor deve iniciar seu funcionamento, o qual deve ficar em alto no inicio da execução de cada processo. Como o processador executa instruções sequencialmente e não tem conhecimento sobre o início de execução de processos, é tarefa do escalonador do sistema operacional definir o momento em que o monitor deve iniciar ou terminar seu funcionamento. A instrução é provida pelo estágio de execução do pipeline do processador, sendo que o sinal de valid_instruction indica se tal instrução deve ou não ser execu- tada pelo processador. Sempre que existe um falta de cache ou uma latência para a completude de instruções de ponto flutuante, entre outros exemplos, este sinal é habilitado indicando ao processador que a instrução não é válida para ser executada.

Após a chegada de uma instrução válida, ocorre a decodificação, processo no qual o opcode é extraído, sendo a instrução classificada. No ciclo posterior a decodificação, o sinal relacionado ao tipo de instrução é habilitado. No caso do exemplo da Figura 4.4, o sinal load_store_instruction fica em alto no ciclo após a decodificação, indicando que uma instrução de load/store acabou de entrar para a execução. Pode-se perceber, que o sinal valid_instruction fica em baixa logo após o primeiro ciclo da instrução. Esse comportamento indica a ocorrência de um stall, momento no qual o processador não está efetiva- mente executando uma instrução, mas está dependendo de algum resultado ou latência de carregamento para continuar sua execução. Os dois sinais, D- TLB-hold e D-CACHE-hold, são providos pela TLB de dados e cache de dados, respectivamente. Quando um desses sinais está em alta, houve a ocorrência de uma falta. No caso do exemplo da Figura 4.4, durante o período de falta, o processador não executa instruções pois está dependendo da leitura do ende- reço físico, provido pela MMU onde o TLB está localizado, para então poder ler o dado requerido da memória. Porém, o exemplo ilustra a situação que após a ocorrência da falta na TLB, com o endereço físico já conhecido, ocorre uma falta na cache para este endereço. Sendo assim, mais ciclos são despendidos até a leitura do dado na memória.

Todos os ciclos gastos com stalls são contabilizados nos componentes que, no caso do exemplo da Figura 4.4, são: cpi_comp_dtlb_stall, cpi_comp_dcache_- stall e cpi_comp_load_store_stall. Quando o sinal D-TLB-hold está em alta, é incrementado o contador relacionado ao componente de stall da TLB de dados. Do mesmo modo ocorre para o sinal D-CACHE-hold, o qual é contabilizado por

Sinal que indica o início do monitoramento

Sinais provindos da D-Cache e do D-TLB

Componentes de stall (contadores de ciclos gastos)

CLK start instruction 0x00 0x44050050 0xFF005054 valid_instruction load_store_instruction D-TLB-hold D-CACHE-hold cpi_comp_dtlb_stall 0 1 2 cpi_comp_dcache_stall 0 1 cpi_comp_load_store_stall 0 1

Figura 4.4: Diagrama da forma de onda de um exemplo de interação com D-TLB e D-CACHE

meio do componente cpi_comp_dcache_stall. Pode-se perceber nesse exemplo, que logo após a descida do sinal D-CACHE-hold, o processador permanece um ciclo ainda em estado inválido. Esse ciclo é interpretado como sendo a latência do pipeline. Essa latência pode ocorrer onde existem dependências de dados entre duas instruções sequenciais ou, principalmente, em casos de saltos onde o processador gasta ciclos invalidando instruções já carregadas para carregar novas instruções em seu pipeline. Assim como mencionado na Seção 3.5, o compoente cpi_comp_load_store_stall consiste nesse tempo de latência do pipeline. que ocorre principalmente entre instruções onde a ins- trução corrente depende do dado carregado pela instrução anterior.

Assim como no caso de instruções de load/store as instruções de saltos também possuem o mesmo tipo de abordagem, com interfaces com a cache de instruções e TLB de instruções.

A Figura 4.5 ilustra um exemplo mais simples, onde não é considerada a interação com componentes externos. Seguindo a premissa de execução em ordem, aplica-se o mesmo método de monitoramento do exemplo anterior. A instrução válida é decodificada, sendo classificada como uma instrução de ponto flutuante. A partir desse momento é realizada uma contagem de ci- clos em que a instrução permanece inválida, estado no qual o processador encontra-se em espera pelo resultado. Assim que o sinal valid_instruction volta a ficar em alta, o contador para de incrementar, e uma nova instrução é decodificada. Essa abordagem pode ser utilizada em outros tipos de compo- nente, tais como divisão e multiplicação.

Sinal que indica o início do monitoramento

Componente de stall de operações de ponto flutuante

CLK start instruction 0x00 0x24F51140 0x800020DE valid_instruction float_point_instruction cpi_comp_fpu_stall 0 1 2 3 4

Figura 4.5: Diagrama da forma de onda do monitoramento de instruções de ponto flutuante

ção, é estritamente aplicável a processadores com fluxo de execução in-order. Evidentemente, cada processador possui uma arquitetura diferente para a execução de instruções. Este modelo de monitoramento propõe um caso ge- ral, que pode ser aplicado para a maioria dos casos de processadores e classes de stalls.

4.5 Pesos de desempenho dos processadores

Conforme mencionado na Seção 3.6, os vetores de pesos dos processadores devem ser calculados por meio de calibração em software e são utilizados nos cálculos de normalização e projeção de desempenho. Como os componentes responsáveis por esses cálculos são implementados em hardware (Figura 4.1), esses vetores devem ser armazenados dentro do bloco do escalonador, de modo que os componentes que realizam a normalização e projeção possam ler os valores dos pesos. Esse armazenamento deve ser realizado por meio de uma memória interna do escalonador em hardware, cuja a estrutura deve respeitar a Tabela 4.1;

Tabela 4.1: Tabela de pesos a ser carregada em memória interna do bloco de escalonamento em hardware

Componente CPU0 CPU1 CPUN

cpi_comp_fpu_stall peso(fpu, cpu0) peso(fpu, cpu1) ...

cpi_comp_mul_stall peso(mul, cpu0) peso(mul, cpu1) ...

cpi_comp_div_stall peso(div, cpu0) peso(div, cpu1) ...

cpi_comp_load_store_stall peso(lo/st, cpu0) peso(lo/st, cpu1) ...

cpi_comp_branch_stall peso(branch,cpu0) peso(branch,cpu1) ...

cpi_comp_dcache_stall peso(dcache,cpu0) peso(dcache,cpu1) ...

cpi_comp_icache_stall peso(icache,cpu0) peso(icache,cpu1) ...

cpi_comp_dtlb_stall peso(dtlb,cpu0) peso(dtlb,cpu1) ...