500 likes | 642 Views
Previsão de Desvio, Superescalar, VLIW e Software Pipelining. Revisão: Tomasulo. Evita conflitos WAR, WAW sem espera Permite desenrolamento de loop em HW Não limitado a blocos básicos (provê previsão de desvio) Contribuições Escalação Dinâmica Renomeação de Registradores
E N D
Revisão: Tomasulo • Evita conflitos WAR, WAW sem espera • Permite desenrolamento de loop em HW • Não limitado a blocos básicos (provê previsão de desvio) • Contribuições • Escalação Dinâmica • Renomeação de Registradores • Tratamento separado de Load e Store • Descendentes do 360/91 são PowerPC 604, 620; MIPS R10000; HP-PA 8000; Intel Pentium Pro, II, III, IV
Previsão estática de desvio • Análise de desvios pelo software (compilador), e tomada de medidas para melhoria do desempenho • Exemplo: desenrolamento de loops, para diminuir a quantidade de desvios.
Previsão Dinâmica de Desvio (hardware) Previsão Local: uma instrução de desvio Global: várias instruções de desvio • Previsão Local Simples: usa apenas um bit Usa-se a tabela – Branch History Table – BHT - de um bit, onde o índice de entrada é a parte menos significativa da instrução de branch BNEZ R1, Loop • O bit diz se o desvio aconteceu ou não da última vez • Em um loop, causa dois erros de previsões: • Início: a previsão é não fazer loop • Fim: a previsão é fazer loop
Exemplo Loop: LD F0 0 R1 MULTD F4 F0 F2 SD F4 0 R1 SUBI R1 R1 #8 BNEZ R1 Loop Considerando-se que no início R1 é igual a 80, e bit de previsão igual a 0 (não desvia). INÍCIO: Primeira execução de BNEZ: como R1 = 80, desvia, ocorre erro de previsão, muda a previsão na BHT para 1 (desvia). Execução de BNEZ subseqüentes: enquanto R1 > 0, desvia, previsão é correta a previsão na BHT continua 1 (desvia). FIM: Última execução de BNEZ: como R1 = 0, não desvia, ocorre erro de previsão, muda a previsão na BHT para 0 (não desvia).
Previsão Local usando 2 bits • a previsão muda somente quando ocorrerem dois erros: • Incrementa quando ocorre desvio • Decrementa quando não ocorre desvio início
Exemplo No início R1 é igual a 80, e bit de previsão igual a 00(não desvia). INÍCIO: Primeira execução de BNEZ: como R1 = 80, desvia, ocorre erro de previsão, muda a previsão na BHT para 01 (não desvia). Segunda execução de BNEZ: como R1 = 72, desvia, ocorre erro de previsão, muda a previsão na BHT para 11 (desvia). Execução de BNEZ subseqüentes: enquanto R1 > 0, desvia, previsão é correta a previsão na BHT continua 11 (desvia). FIM: Última execução de BNEZ: como R1 = 0, não desvia, ocorre erro de previsão, muda a previsão na BHT para 10 (desvia). Loop: ................................................................. SUBI R1 R1 #8 BNEZ R1 Loop Na primeira execução do programa ocorrem 2 erros de previsão, porém, a partir da próxima vez ocorre apenas 1 erro.
Previsão com correlação entre loops If (aa == 2) aa = 0; If (bb == 2) bb = 0; If (aa!=bb) DSUBUI R3,R1,#2 BNEZ R3,L1 ; desvio b1 (aa!=2) DADD R1,R0,R0 ; aa = 0 L1: DSUBUI R3,R2,#2 BNEZ R3,L2 ; desvio b2 (bb !=2) DADD R2,R0,R0 ; bb=0 L2: DSUBU R3,R1,R2 ; R3 = aa-bb BEQZ R3,L3 ; desvio b3 (aa==bb) Se não ocorrem desvios b1 e b2 então ocorre desvio b3 O previsor faz a correlação entre loops!! aa 0 bb
Outro exemplo desvio com correlação if (d ==0) d = 1; if (d ==1) Código MIPS: BNEZ R1,L1 ; desvio b1 (d!=0) DADDIU R1,R0,#1 ; d==0 , então d =1 L1: DADDIU R3,R1,#-1 ; R3 = d -1 BNEZ R3,L2 ; desvio b2 (d!=1) ... L2: d 0
Possível seqüência de execução BNEZ R1,L1 ; desvio b1 (d!= 0) DADDIU R1,R0,#1 ; d==0 , então d =1 L1: DADDIU R3,R1,#-1 ; R3 = d - 1 BNEZ R3,L2 ; desvio b2 (d!=1) ... L2: d antes do desvio b1 d==0? d antes do desvio b2 b1 d==1? b2 1 sim not taken not taken 0 sim 1 sim not taken taken 1 não 2 não taken taken 2 não
Comportamento de um previsor de 1 bit BNEZ R1,L1 ; desvio b1 (d!= 0) DADDIU R1,R0,#1 ; d==0 , então d =1 L1: DADDIU R3,R1,#-1 ; R3 = d - 1 BNEZ R3,L2 ; desvio b2 (d!=1) ... L2: Sequência dada nova previsão para b1 nova previsão para b2 previsão de b1 ação de b1 previsão de b2 ação de b2 d = ? T NT T T NT T 2 NT T NT NT T NT 0 T NT T T NT T 2 NT T NT NT T NT 0 Resultado: todas as previsões foram incorretas.
Previsor de 1 bit com correlação • Para cada desvio tem duas previsões (a/b), sendo que para um determinado momento vale uma das previsões: a ou b a - se o último desvio do programa é NT b - se o último desvio do programa é T notando-se que o último desvio do programa normalmente não é o desvio que está sendo previsto, e sim, o que está sendo correlacionado. se o último desvio do programa foi NT usa-se o lado (a ) se o último desvio do programa foi T usa-se o lado ( b) bits de previsão (a/b) previsão = NT NT/NT previsão = NT previsão = T NT/T previsão = NT previsão = NT T/NT previsão = T previsão = T T/T previsão = T
Sequência dada Aplicação no exemplo nova previsão para b1 nova previsão para b2 previsão de b1 ação de b1 previsão de b2 ação de b2 d = ? T/NT NT/NT T NT/T NT/NT T 2 T/NT NT/T NT NT/T T/NT NT 0 T/NT NT/T T NT/T T/NT T 2 T/NT NT/T NT NT/T T/NT NT 0 a/b – usa previsão b a/b – usa previsão a Resultado – apenas 2 erros de previsão iniciais.
Previsão por torneio (Tournament predictor)A forma mais comum para previsão multi-nível LOCAL GLOBAL O contador é incrementado sempre que o previsor usado é correto e outro incorreto, e decrementado caso contrário. Quando ambos estão corretos ou incorretos, mantém o estado.
Endereço de desvio junto com previsão (Branch Target Buffer – BTB) • Endereço da instrução (PC) é usado como índice do BTB para obter a previsão e endereço de desvio • Retorna o endereço da instrução prevista
Suporte de HW para mais ILP (Instruction Level Parallelism) • Evita desvio em programas incluindo operações (predicados) dentro das instruções condicionais: • if (x) then A = B op C else NOP • se (x) falso, então não ocorre nenhuma operação • IA-64: tem campos de condição de 1-bit para execução condicional de instruções • Vantagem • Evita desvio • Desvantagens • Toma tempo (clock) mesmo que anulada • Espera enquanto a condição é avaliada • Condições complexas reduzem a eficiência, implicam em atraso de pipeline x A = B op C
Previsão Dinâmica de Desvio Sumário • Correlação: Desvios executados recentemente correlacionados com o desvio seguinte • Branch Target Buffer: inclui endereço de desvio & previsão • Execução com predicado pode reduzir o número de desvios, número de erros em previsões
Tornando CPI < 1: EmitindoMúltiplas Instruções/Ciclo • Duas variações • Superscalar: variando número de instruções/ciclo (1 a 8), escalados pelo compilador ou por HW (Tomasulo) • IBM PowerPC, Sun UltraSparc, DEC Alpha, HP 8000 • Very Long Instruction Words - VLIW: • instruções paralelizáveis (4 a16) escalados pelo compilador; • coloca as instruções dispostas como uma única instrução longa
Tornando CPI < 1: EmitindoMúltiplas Instruções/Ciclo • Superscalar MIPS: 2 instruções, 1 FP & 1 outra qualquer – Busca (fetch) 64-bits/ciclo de clock (Int. e FP) Tipo Estágios de Pipeline Int. instruction IF ID EX MEM WB FP instruction IF ID EX MEM WB Int. instruction IF ID EX MEM WB FP instruction IF ID EX MEM WB Int. instruction IF ID EX MEM WB FP instruction IF ID EX MEM WB
Revisão: desenrolamento de loops para minimizar paradas em MIPS pipeline 1 Loop: LD F0,0(R1) 2 LD F6,-8(R1) 3 LD F10,-16(R1) 4 LD F14,-24(R1) 5 ADDD F4,F0,F2 6 ADDD F8,F6,F2 7 ADDD F12,F10,F2 8 ADDD F16,F14,F2 9 SD F4,0(R1) 10 SD F8,-8(R1) 11 SD F12,-16(R1) 12 SUBI R1,R1,#32 13 BNEZ R1,LOOP 14 SD F16,8(R1) ; 8-32 = -24 14 ciclos de clock, ou 3.5 por iteração CPI = 1
LD para ADDD: 2 Ciclos ADDD para SD: 2 Ciclos Desenrolamento em Superscalar Integer instruction FP instruction Clock cycle Loop: LD F0,0(R1) 1 LD F6,-8(R1) 2 LD F10,-16(R1) ADDD F4,F0,F2 3 LD F14,-24(R1) ADDD F8,F6,F2 4 LD F18,-32(R1) ADDD F12,F10,F2 5 SD F4,0(R1) ADDD F16,F14,F2 6 SD F8,-8(R1) ADDD F20,F18,F2 7 SD F12,-16(R1) 8 SD F16,-24(R1) 9 SUBI R1,R1,#40 10 BNEZ R1,LOOP 11 SD F20,-32(R1) 12 • Desenrola 5 vezes para evitar atrasos • 12 clocks, ou 2.4 clocks por iteração • CPI = 12 / 17 = ~0.7
Desafio de Múltipla Emissão para superescalar • Enquanto a separação em Inteiros e FPs seja simples em HW, o CPI de 0.5 é possível somente para programas com: • Exatamente 50% de operações FP • Sem conflitos • É difícil: emitir ao mesmo tempo, mais que duas instruções • É também difícil decidir se 2 instruções escalares podem ser emitidas ao mesmo tempo => examinar 2 opcodes, 6 especificadores de registradores,...
VLIW (Very Large Instruction Word) • A palavra de instrução longa tem espaço para muitas operações • Todas as operações que o compilador coloca na palavra de instrução longa são independentes => execução em paralelo • Ex.: 2 operações inteiras, 2 operações FP, 2 refer. memória, 1 desvio • 16 a 24 bits por campo => 7*16 ou 112 bits a 7*24 ou 168 bits Necessita de técnicas de compilação que faz a escalação passando por vários desvios
Desenrolamento em VLIW Memory Memory FP FP Int. op/ Clockreference 1 reference 2 operation 1 op. 2 branch LD F0,0(R1) LD F6,-8(R1) 1 LD F10,-16(R1) LD F14,-24(R1) 2 LD F18,-32(R1) LD F22,-40(R1) ADDD F4,F0,F2 ADDD F8,F6,F2 3 LD F26,-48(R1) ADDD F12,F10,F2 ADDD F16,F14,F2 4 ADDD F20,F18,F2 ADDD F24,F22,F2 5 SD F4,0(R1) SD F8,-8(R1) ADDD F28,F26,F2 6 SD F12,-16(R1) SD F16,-24(R1) 7 SD F20,-32(R1) SD F24,-40(R1) SUBI R1,R1,#48 8 SD F28,-0(R1) BNEZ R1,LOOP 9 Desenrola 7 vezes para evitar atrasos 7 resultados em 9 clocks, ou 1.3 clocks por iteração CPI = 23/9 = ~0.39 Nota: Necessita mais registradores em VLIW (15 vs. 6 em Superescalar)
Geração de código para VLIW - Trace Scheduling • Dois passos: • Seleção de Traço (Trace) • Encontrar uma sequência provável de blocos básicos, traço, de uma longa sequência de códigos • Compactação de Traço • Espremer o traço em algumas instruções VLIW • Necessita de código alternativo no caso de erro de previsão de código
Tamanho de código menor Compatibilidade através de gerações de hardware Hardware Simplificado para decodificação e emissão de instruções Sem conflito entre as instruções Mais registradores Superscalar vs. VLIW
Software Pipelining • Observação: se iterações de loops são independentes, pode-se obter mais ILP tomando instruções de diferentesiterações • Software pipelining: reorganiza loops tal que cada iteração seja composta de instruções de diferentes iterações do loop original
Exemplo de Software Pipelining ITERAÇÃO 0 ITERAÇÃO 1 ITERAÇÃO 2 1 LD F0,0(R1) 2 ADDD F4,F0,F2 3 SD F0,0(R1) 4 SUBI R1,R1,#8 5 BNEZ R1,LOOP 1 LD F0,0(R1) 2 ADDD F4,F0,F2 3 SD F0,0(R1) 4 SUBI R1,R1,#8 5 BNEZ R1,LOOP 1 LD F0,0(R1) 2 ADDD F4,F0,F2 3 SD F0,0(R1) 4 SUBI R1,R1,#8 5 BNEZ R1,LOOP
Exemplo de Software Pipelining Após: Software Pipeline 1 SD F4,0(R1); Stores M[i] 2 ADDD F4,F0,F2 ; Adds to M[i-1] 3 LD F0,-16(R1); Loads M[i-2] 4 SUBI R1,R1,#8 5 BNEZ R1,LOOP Antes: desenrolado 3 vezes 1 LD F0,0(R1) 2 ADDD F4,F0,F2 3 SD F4,0(R1) 4 LD F6,-8(R1) 5 ADDD F8,F6,F2 6 SD F8,-8(R1) 7 LD F10,-16(R1) 8 ADDD F12,F10,F2 9 SD F12,-16(R1) 10 SUBI R1,R1,#24 11 BNEZ R1,LOOP SW Pipeline Ops. sobrepostas Tempo Loop Unrolled Tempo
Intel/HP-IA-64 (ITANIUM ) “Explicitly Parallel Instruction Computer (EPIC)” • Explora a arquitetura VLIW, deixando a detecção do ILP(Instruction Level Parallelism) para os compiladores • 3 Instruções em “grupos” de 128 bits; campos determinam se as instruções são dependentes ou independentes • 64 registradores inteiros + 64 registradores ponto flutuante • Hardware checa dependências • Execução com Predicado => 40% menos previsões errôneas • IA-64 : nome da arquitetura do conjunto de instruções • Itanium - implementação • Suporte para instruções IA-32, porém com desempenho menor que as últimas versões do Pentium, por explorarem mais o desempenho nas instruções EPIC (VLIW) e não terem suportes de ILP por hardware.
Análise de desempenho do Pentium 4 inteiros Ponto flutuante
Erro de especulação em instruções uop inteiros Ponto flutuante
Falta em caches L1 e L2 por 1000 instruções inteiros Cache L2 Cache L1 Ponto flutuante
CPI inteiros Ponto flutuante
Pentium 4 x AMD Opteron inteiros Ponto flutuante
Desempenho do AMD Opteron x Pentium 4 inteiros Ponto flutuante
IBM Power5 x Pentium 4 Ponto flutuante inteiros
Processador ideal • Todas as restrições de ILP são removidas • 1- renomeação de registrador – um número infinito de registradores virtuais à disposição, por isso todos os WAW e WAR são evitados e um número infinito de instruções pode iniciar simultaneamente • 2- previsão de desvio – a previsão é perfeita • 3- previsão de salto – todos os saltos são previstos • 4- análise de alias de endereço de memória - todos os endereços de memória são conhecidos, e um load pode ser feito antes de um store, desde que os endereços não sejam iguais. • 5- caches perfeitos – todos os endereços de memória usam 1 ciclo.
ILP num processador ideal inteiros Ponto flututante
O que um processador ideal precisa fazer • 1- olhar muito adiante para encontrar um conjunto de instruções a despachar (emitir), prevendo todos os desvios perfeitamente • 2- renomear todos os usos de registrador para evitar WAR e WAW • 3- determinar se existem dependências de dados entre as instruções no pacote de emissão; se houver renomear adequadamente • 4- determinar se existe alguma dependência de memória entre as instruções sendo emitidas e tratar delas adequadamente • 5- oferecer unidades funcionais replicadas suficientes para que todas as instruções prontas sejam emitidas
Efeitos da limitação da janela inteiros Ponto flutuante
Redução do paralelismo pelo número de registradores para renomeação Fig.3.5
Efeito de níveis variados de análise de alias sobre programas