Como já vimos anteriormente, alguns processadores podem executar múltiplas instruções simultaneamente. Por vezes nem todos os resultados das execuções serão usados, devido a alterações no fluxo do programa. Isto pode ocorrer particularmente na vizinhança de branches ou ramificações, onde uma condição é testada e a sequência do programa é alterada dependendo do resultado dessa análise.
Branches são muito comuns no código x86 e poderão ser um sério problema para o pipeling, porque não podemos ter a certeza que as instruções serão executadas numa sequência linear. Pipelining é sinónimo de executar a instrução seguinte antes que a primeira esteja completa. Quando se trata de instruções de teste condicional, isto é, uma instrução tipo “if…then”, não sabemos qual é a instrução seguinte até que a instrução de teste condicional seja totalmente executada, pelo que não se sabe que instrução deverá ir em seguida para a pipeline.
Num processador menos actual, acontece parar a pipeline até que os resultados sejam totalmente conhecidos, tendo como consequência um decréscimo de performance. Processadores mais recentes tratam esse problema de um modo diferente, ou seja, executam especulativamente a instrução seguinte, com a esperança de poder usar os resultados se o branch for para o lado que ele julga que vai, daí a expressão speculative execution. Mas os processadores actuais combinam o speculative execution com uma outra técnica, o branch prediction, a qual permite ao processador, baseado no fluxo do programa e em instruções anteriores, prever com alguma precisão para que lado irá o branch.
Tomemos o seguinte exemplo:
IF A = B THEN
C = C + 1
ELSE
C = C - 1
END IF
A instrução “IF THEN” é um branch ou, melhor dizendo, uma ramificação. Até que esteja completamente executada, não sabemos se a próxima instrução será uma adição ou uma subtracção. Um processador que execute especulativamente pode arrancar tanto a adição como a subtracção simultaneamente, e pura e simplesmente esquece aquela que não interessar. Ou pode fazer uso do branch prediction para arrancar somente uma delas, aquela que ele considerar ser a mais indicada para se o resultado da instrução “IF”.
O branch prediction aperfeiçoa o manuseamento dos branches fazendo uso de uma pequena cache chamada branch target buffer ou BTB. Sempre que o processador executa um branch, ele armazena informações acerca do branch nessa área. Quando o processador encontra novamente o mesmo branch, ele é capaz de saber qual a melhor solução. Isto ajuda a manter o fluxo de instruções na pipeline e aumenta a performance. Quanto maior for o BTB, mais informação acerca dos branches é capaz de manter.
Sem comentários:
Enviar um comentário