Optimização do Desempenho: Técnicas Dependentes da Máquina

34
Optimização do Desempenho: Técnicas Dependentes da Máquina Arquitectura de Computadores Lic. em Engenharia Informática Luís Paulo Santos

description

Optimização do Desempenho: Técnicas Dependentes da Máquina. Arquitectura de Computadores Lic. em Engenharia Informática Luís Paulo Santos. Optimização: Dependência do Processador. Optimização de combine(). void combine4(vec_ptr v, int *dest) { int i; int length = vec_length(v); - PowerPoint PPT Presentation

Transcript of Optimização do Desempenho: Técnicas Dependentes da Máquina

Page 1: Optimização do Desempenho: Técnicas Dependentes da Máquina

Optimização do Desempenho:Técnicas Dependentes da Máquina

Arquitectura de ComputadoresLic. em Engenharia Informática

Luís Paulo Santos

Page 2: Optimização do Desempenho: Técnicas Dependentes da Máquina

Optimização: Dependência do Processador

2

Conteúdos

10 – Optimização do Desempenho

10.3 – Super-escalaridade e Execução fora-de-ordem 10.4 – Loop Unrolling/Splitting

Resultados de Aprendizagem

R10.1 – Descrever, aplicar e avaliar técnicas de optimização de desempenho R10.2 – Analisar e justificar o impacto de múltiplas unidades funcionais no desempenho da máquina

Page 3: Optimização do Desempenho: Técnicas Dependentes da Máquina

Optimização de combine()

3

• Função– Calcula a soma de todos os elementos de um vector

– Alcançou um CPE de 2.00• Ciclos por elemento

void combine4(vec_ptr v, int *dest){ int i; int length = vec_length(v); int *data = get_vec_start(v); int sum = 0; for (i = 0; i < length; i++) sum += data[i]; *dest = sum;}

Page 4: Optimização do Desempenho: Técnicas Dependentes da Máquina

Forma Geral de combine()

4

•Tipos de Dados– Usar diferentes declarações

para data_t– int– float

void abstract_combine4(vec_ptr v, data_t *dest){ int i; int length = vec_length(v); data_t *data = get_vec_start(v); data_t t = IDENT; for (i = 0; i < length; i++) t = t OP data[i]; *dest = t;}

•Operações– Diferentes definições paraOP e IDENT

– + / 0– * / 1

Page 5: Optimização do Desempenho: Técnicas Dependentes da Máquina

Optimizações Independentes da Máquina

5

Método Integer Floating Point + * + *

-g 42.06 41.86 41.44 160.00 -O2 31.25 33.25 31.25 143.00 Mover vec_length 20.66 21.25 21.15 135.00 acesso dados 6.00 9.00 8.00 117.00 Acum. em temp 2.00 4.00 3.00 5.00

• Anomalia Desempenho– Grande optimização quando o produto FP é acumulado em

temp:• A Memória usa formato de 64-bits, os registos usam 80 bits• A operação causou overflow com 64 bits, mas não com 80

Page 6: Optimização do Desempenho: Técnicas Dependentes da Máquina

Processadores Actuais

6ExecutionExecution

FunctionalUnits

Instruction ControlInstruction Control

Integer/Branch

FPAdd

FPMult/Div

Load Store

InstructionCache

DataCache

FetchControl

InstructionDecode

Address

Instrs.

Operations

PredictionOK?

DataData

Addr. Addr.

GeneralInteger

Operation Results

RetirementUnit

RegisterFile

RegisterUpdates

Page 7: Optimização do Desempenho: Técnicas Dependentes da Máquina

Unidades Funcionais: Desempenho (Pentium III)

7

• Múltiplas Instruções podem ser executadas em Paralelo– 1 load (leitura da memória)– 1 store (escrita na memória)– 2 operações inteiras (apenas uma pode ser um salto)– 1 Adição FP– 1 Multiplicação ou Divisão FP

• Algumas Instruções necessitam de > 1 Ciclo, mas podem ser em encadeadas (pipeline)– Instrução Latência Ciclos entre Operações– Load / Store 3 1– Multiplicação Inteira 4 1– Divisão Inteira 36 36– Multiplicação FP 5 2– Adição FP 3 1– Divisão FP 38 38

Page 8: Optimização do Desempenho: Técnicas Dependentes da Máquina

Controlo das Instruções

8

Instruction ControlInstruction Control

InstructionCache

FetchControl

InstructionDecode

Address

Instrs.

Operations

RetirementUnit

RegisterFile

• Lê Instruções da Memória– Baseada no PC + alvos previstos para os saltos– Hardware prevê dinamicamentes se os saltos são tomados ou não

• Traduz Instruções em Micro-Operações– Micro-Operação: passos elementares para a execução de uma instrução– Instrução típica requer 1–3 micro-operações

• Referências aos registos são substituídas por etiquetas– Etiqueta: Identificador abstracto liga o destino de uma operação aos operandos das

próximas

Page 9: Optimização do Desempenho: Técnicas Dependentes da Máquina

Tradução em micro-operações: Exemplo

9

• Combine4(): dados inteiros, multiplicação.L24: # Loop:imull (%eax,%edx,4),%ecx # t *= data[i]incl %edx # i++cmpl %esi,%edx # i:lengthjl .L24 # if < goto Loop

.L24:

imull (%eax,%edx,4),%ecx

incl %edxcmpl %esi,%edxjl .L24

load (%eax,%edx.0,4) t.1imull t.1, %ecx.0 %ecx.1incl %edx.0 %edx.1cmpl %esi, %edx.1 cc.1jl-taken cc.1

• Tradução de uma iteração:

Page 10: Optimização do Desempenho: Técnicas Dependentes da Máquina

Tradução em micro-operações: imull

10

– Dividir em 2 operações• load lê da memória e produz o valor t.1• imull opera apenas sobre registos

– Operandos• %eax não muda no ciclo. Lido do banco de registos durante o

decode• %ecx muda em cada iteração. Identificar diferentes versões com %ecx.0, %ecx.1, %ecx.2, …

– Register renaming– Valores passam directamente do produtor aos consumidores

imull (%eax,%edx,4),%ecx load (%eax,%edx.0,4) t.1imull t.1, %ecx.0 %ecx.1

Page 11: Optimização do Desempenho: Técnicas Dependentes da Máquina

Tradução em micro-operações: incl, cmpl

11

– %edx muda em cada iteração. Renomear %edx.0, %edx.1, %edx.2, …

incl %edx incl %edx.0 %edx.1

– Códigos de Condição são tratados como registos

cmpl %esi,%edx cmpl %esi, %edx.1 cc.1

Page 12: Optimização do Desempenho: Técnicas Dependentes da Máquina

Tradução em micro-operações: jl

12

– Instruction control determina destino do salto

– Prevê se é tomado ou não

– Instruções são lidas do destino previsto

– Execution unit verifica se previsão foi correcta– Se não, sinaliza instruction control

• Instruction control invalida operações e valores gerados por instruções lidas inadvertidamente

• Começa então a ler instruções a partir do endereço correcto

jl .L24 jl-taken cc.1

Page 13: Optimização do Desempenho: Técnicas Dependentes da Máquina

Visualização da execução das μoperações -imull

13

• Operações– Eixo Vertical determina tempo

• Uma operação não pode começar antes de os operandos estarem disponíveis

– Altura representa latência• Operandos

– Representados por arcos

cc.1

t.1

load

%ecx.1

incl

cmpl

jl

%edx.0

%edx.1

%ecx.0

imull

load (%eax,%edx,4) t.1imull t.1, %ecx.0 %ecx.1incl %edx.0 %edx.1cmpl %esi, %edx.1 cc.1jl-taken cc.1

Time

Page 14: Optimização do Desempenho: Técnicas Dependentes da Máquina

Visualização da execução das μoperações -addl

14

• Operações– Idêntico ao anterior, mas

adição tem latência=1

Time

cc.1

t.1

%ecx.i +1

incl

cmpl

jl

load

%edx.0

%edx.1

%ecx.0

addl%ecx.1

load

load (%eax,%edx,4) t.1iaddl t.1, %ecx.0 %ecx.1incl %edx.0 %edx.1cmpl %esi, %edx.1 cc.1jl-taken cc.1

Page 15: Optimização do Desempenho: Técnicas Dependentes da Máquina

Execução imull: Recursos Ilimitados

15

cc.1

cc.2%ecx.0

%edx.3t.1

imull

%ecx.1

incl

cmpl

jl

%edx.0

i=0

load

t.2

imull

%ecx.2

incl

cmpl

jl

%edx.1

i=1

load

cc.3

t.3

imull

%ecx.3

incl

cmpl

jl

%edx.2

i=2

load

Cycle

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

cc.1

cc.2

Iteration 3

Iteration 2

Iteration 1

cc.1

cc.2%ecx.0

%edx.3t.1

imull

%ecx.1

incl

cmpl

jl

%edx.0

i=0

load

t.1

imull

%ecx.1

incl

cmpl

jl

%edx.0

i=0

load

t.2

imull

%ecx.2

incl

cmpl

jl

%edx.1

i=1

load

t.2

imull

%ecx.2

incl

cmpl

jl

%edx.1

i=1

load

cc.3

t.3

imull

%ecx.3

incl

cmpl

jl

%edx.2

i=2

load

Cycle

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

Cycle

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

cc.1

cc.2

Iteration 3

Iteration 2

Iteration 1

• 3 iterações– Assume que as

operações podem começar logo que os operandos estão disponíveis

– Operações de diferentes iterações sobrepõem-se no tempo

• Desempenho– Limitado pela latência

da unidade de multiplicação

– CPE = 4.0

Page 16: Optimização do Desempenho: Técnicas Dependentes da Máquina

Execução addl: Recursos Ilimitados

16

• Desempenho– Começa uma nova iteração a cada ciclo– CPE = 1.0– Requer a execução de 4 operações inteiras em paralelo

%edx.0

t.1

%ecx.i +1

incl

cmpl

jl

addl%ecx.1

i=0

loadcc.1

%edx.0

t.1

%ecx.i +1

incl

cmpl

jl

addl%ecx.1

i=0

loadcc.1

%edx.1

t.2

%ecx.i +1

incl

cmpl

jl

addl%ecx.2

i=1

loadcc.2

%edx.1

t.2

%ecx.i +1

incl

cmpl

jl

addl%ecx.2

i=1

loadcc.2

%edx.2

t.3

%ecx.i +1

incl

cmpl

jl

addl%ecx.3

i=2

loadcc.3

%edx.2

t.3

%ecx.i +1

incl

cmpl

jl

addl%ecx.3

i=2

loadcc.3

%edx.3

t.4

%ecx.i +1

incl

cmpl

jl

addl%ecx.4

i=3

loadcc.4

%edx.3

t.4

%ecx.i +1

incl

cmpl

jl

addl%ecx.4

i=3

loadcc.4

%ecx.0

%edx.4

Cycle

1

2

3

4

5

6

7

Cycle

1

2

3

4

5

6

7

Iteration 1

Iteration 2

Iteration 3

Iteration 4

4 ops inteiras

Page 17: Optimização do Desempenho: Técnicas Dependentes da Máquina

Execução addl: Recursos Limitados

17

Iteration 4

Iteration 5

Iteration 6

Iteration 7

Iteration 8

%ecx.3

%edx.8

%edx.3

t.4%ecx.i +1

incl

cmpl

jladdl

%ecx.4

i=3

load

cc.4

%edx.3

t.4%ecx.i +1

incl

cmpl

jladdl

%ecx.4

i=3

load

cc.4

%edx.4

t.5%ecx.i +1

incl

cmpl

jladdl%ecx.5

i=4

load

cc.5

%edx.4

t.5%ecx.i +1

incl

cmpl

jladdl%ecx.5

i=4

load

cc.5

cc.6

%edx.7

t.8%ecx.i +1

incl

cmpl

jladdl

%ecx.8

i=7

load

cc.8

%edx.7

t.8%ecx.i +1

incl

cmpl

jladdl

%ecx.8

i=7

load

cc.8

%edx.5

t.6

incl

cmpl

jl

addl

%ecx.6

load

i=5

%edx.5

t.6

incl

cmpl

jl

addl

%ecx.6

load

i=5

6

7

8

9

10

11

12

Cycle

13

14

15

16

17

6

7

8

9

10

11

12

Cycle

13

14

15

16

17

18

cc.6

%edx.6

t.7

cmpl

jl

addl

%ecx.7

load

cc.7

i=6

incl

%edx.6

t.7

cmpl

jl

addl

%ecx.7

load

cc.7

i=6

incl

– Apenas 2 unidades funcionais para operações inteiras– Algumas operações esperam por recursos apesar de os

operandos estarem disponíveis– Prioridade das ops baseada na order do programa

• Desempenho– CPE = 2.0

Page 18: Optimização do Desempenho: Técnicas Dependentes da Máquina

Escalonamento de μoperações

• 1 μoperação pode ser escalonada para execução quando:

– Os seus operandos estão disponíveis

– Existem recursos disponíveis, isto é, uma unidade funcional livre que a possa executar

18

Page 19: Optimização do Desempenho: Técnicas Dependentes da Máquina

Optimização: Loop unrolling

19

void combine5(vec_ptr v, int *dest){ int length = vec_length(v); int limit = length-2; int *data = get_vec_start(v); int sum = 0; int i; /* Combine 3 elements at a time */ for (i = 0; i < limit; i+=3) { sum += data[i] + data[i+2] + data[i+1]; } /* Finish any remaining elements */ for (; i < length; i++) { sum += data[i]; } *dest = sum;}

As operações de controlo do ciclo representam um custo: • actualização da variável de controlo• teste da condição• salto

Desenrolar do ciclo:• combinar múltiplas operações numa única iteração• reduz custo do controlo do ciclo

CPE = 1.33

Esta optimização pode ser feita autonomamente pelo compilador

Page 20: Optimização do Desempenho: Técnicas Dependentes da Máquina

Visualização: Loop unrolling

20

– Loads encadeados (não têm dependências)

– Apenas 1 conjunto de operações de controlo

load (%eax,%edx.0,4) t.1aiaddl t.1a, %ecx.0c %ecx.1aload 4(%eax,%edx.0,4) t.1biaddl t.1b, %ecx.1a %ecx.1bload 8(%eax,%edx.0,4) t.1ciaddl t.1c, %ecx.1b %ecx.1ciaddl $3,%edx.0 %edx.1cmpl %esi, %edx.1 cc.1jl-taken cc.1

%edx.0

%edx.1

%ecx.0c

cc.1

t.1a

%ecx.i +1

addl

cmpl

jl

addl

%ecx.1c

addl

addl

t.1b

t.1c

%ecx.1a

%ecx.1b

load

load

load

Page 21: Optimização do Desempenho: Técnicas Dependentes da Máquina

Visualização: Loop unrolling

21

i=6

cc.3

t.3a

%ecx.i +1

addl

cmpl

jl

addl

%ecx.3c

addl

addl

t.3b

t.3c

%ecx.3a

%ecx.3b

load

load

load

%ecx.2c

i=9

cc.4

t.4a

%ecx.i +1

addl

cmpl

jl

addl

%ecx.4c

addl

addl

t.4b

t.4c

%ecx.4a

%ecx.4b

load

load

load

cc.4

t.4a

%ecx.i +1

addl

cmpl

jl

addl

%ecx.4c

addl

addl

t.4b

t.4c

%ecx.4a

%ecx.4b

load

load

load

%edx.3

%edx.2

%edx.4

5

6

7

8

9

10

11

Cycle

12

13

14

15

5

6

7

8

9

10

11

Cycle

12

13

14

15

Iteration 3

Iteration 4

Desempenho Previsto• Pode terminar uma iteração em 3 ciclos• CPE deveria ser 1.0

Desempenho Medido• CPE = 1.33• Uma iteração cada 4 ciclos

Page 22: Optimização do Desempenho: Técnicas Dependentes da Máquina

combine5(): resultado de desenrolar o ciclo

22

– Neste exemplo só benefecia a soma de inteiros• Outros casos limitados pela latência das unidades funcionais

– Optimização é não linear com o grau de unrolling• Existem muitos efeitos subtis que condicionam o escalonamento

das operações

Grau de Grau de unrollingunrolling 11 22 33 44 88 1616

IntegerInteger SumSum 2.002.00 1.501.50 1.331.33 1.501.50 1.251.25 1.061.06

IntegerInteger ProductProduct 4.004.00

FPFP SumSum 3.003.00

FPFP ProductProduct 5.005.00

Page 23: Optimização do Desempenho: Técnicas Dependentes da Máquina

Multiplicação: unrolling

23

load

load

load

imull

imull

imull

addl

cmpl

jlNão há vantagem com o desenrolar do ciclo:• não tiramos partido do encadeamento da unidade de multiplicação devido às dependências de operandos

Page 24: Optimização do Desempenho: Técnicas Dependentes da Máquina

Computação em Série

24

• Cálculo ((((((((((((1 * x0) * x1) * x2) * x3)

* x4) * x5) * x6) * x7) * x8) * x9) * x10) * x11)

• Desempenho– N elementos, D ciclos/operação

– Total = N*D ciclos

*

*

11xx00

xx11

*

xx22

*

xx33

*

xx44

*

xx55

*

xx66

*

xx77

*

xx88

*

xx99

*

xx1010

*

xx1111

Page 25: Optimização do Desempenho: Técnicas Dependentes da Máquina

Desenrolar do ciclo paralelo: Loop Spliting

25

– Produto de Inteiros• Optimização

– Acumular em 2 produtos diferentes • Realizados

simultaneamente– Combinar no fim

• Desempenho– CPE = 2.0 (era 4.0)

void combine6(vec_ptr v, int *dest){ int length = vec_length(v); int limit = length-1; int *data = get_vec_start(v); int x0 = 1; int x1 = 1; int i; /* Combine 2 elements at a time */ for (i = 0; i < limit; i+=2) { x0 *= data[i]; x1 *= data[i+1]; } /* Finish any remaining elements */ for (; i < length; i++) { x0 *= data[i]; } *dest = x0 * x1;}

Page 26: Optimização do Desempenho: Técnicas Dependentes da Máquina

Loop Spliting grau 2

26

• Computação ((((((1 * x0) * x2) * x4) * x6) * x8) * x10) *

((((((1 * x1) * x3) * x5) * x7) * x9) * x11)

• Desempenho– N elementos, D ciclos/operação– (N/2+1)*D ciclos – ~2X melhoria no desempenho

*

*

11xx11

xx33

*

xx55

*

xx77

*

xx99

*

xx1111

*

*

11xx00

xx22

*

xx44

*

xx66

*

xx88

*

xx1010

*

Page 27: Optimização do Desempenho: Técnicas Dependentes da Máquina

Requisitos para Loop Spliting

27

• Matemáticos– A operação tem que ser associativa e comutativa

• Multiplicação de inteiros: OK• Não é necessariamente verdade para operações em vírgula

flutuante

• Hardware– Múltiplas unidades funcionais ou unidades funcionais

encadeadas

Page 28: Optimização do Desempenho: Técnicas Dependentes da Máquina

Loop Spliting: Visualização

28

– As multiplicações não dependem uma da outra

– Podem ser executadas em paralelo

load (%eax,%edx.0,4) t.1aimull t.1a, %ecx.0 %ecx.1load 4(%eax,%edx.0,4) t.1bimull t.1b, %ebx.0 %ebx.1iaddl $2,%edx.0 %edx.1cmpl %esi, %edx.1 cc.1jl-taken cc.1

%edx.1

%ecx.0

%ebx.0

cc.1

t.1a

imull

%ecx.1

addl

cmpl

jl

%edx.0

imull

%ebx.1

t.1b

load

load

Page 29: Optimização do Desempenho: Técnicas Dependentes da Máquina

Loop Spliting: Visualização

29

%edx.3%ecx.0

%ebx.0

i=0

i=2

cc.1

t.1a

imull

%ecx.1

addl

cmpl

jl

%edx.0

imull

%ebx.1

t.1b

load

loadcc.1

t.1a

imull

%ecx.1

addl

cmpl

jl

%edx.0

imull

%ebx.1

t.1b

load

loadcc.2

t.2a

imull

%ecx.2

addl

cmpl

jl

%edx.1

imull

%ebx.2

t.2b

load

loadcc.2

t.2a

imull

%ecx.2

addl

cmpl

jl

%edx.1

imull

%ebx.2

t.2b

load

load

i=4

cc.3

t.3a

imull

%ecx.3

addl

cmpl

jl

%edx.2

imull

%ebx.3

t.3b

load

load

14

Cycle

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

Cycle

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

Iteration 1

Iteration 2

Iteration 3

– Desempenho Previsto• Multiplicador 4 ciclos

ocupado com 2 operações simultâneas

• CPE = 2.0

Page 30: Optimização do Desempenho: Técnicas Dependentes da Máquina

Resultados para combine()

30

Método Integer Floating Point + * + *

Abstract -g 42.06 41.86 41.44 160.00 Abstract -O2 31.25 33.25 31.25 143.00 Mover vec_length 20.66 21.25 21.15 135.00 acesso dados 6.00 9.00 8.00 117.00 Acum. em temp 2.00 4.00 3.00 5.00 Unroll x4 1.50 4.00 3.00 5.00 Unroll x16 1.06 4.00 3.00 5.00 Split 2 X 2 1.50 2.00 2.00 2.50 Split 4 X 4 1.50 2.00 1.50 2.50 Split 8 X 4 1.25 1.25 1.50 2.00 Ponto Óptimo Teór. 1.00 1.00 1.00 2.00 Pior/Melhor 39.7 33.5 27.6 80.0

Page 31: Optimização do Desempenho: Técnicas Dependentes da Máquina

Limitações de Spliting

31

• Necessita de muitos registos• Para armazenar somas/produtos temporários– Apenas 6 registos inteiros (na arquitectura IA32)

• Usados também para apontadores e variáveis auxiliares (ex. Ciclo)– 8 registos FP (na arquitectura IA32)

– Se os registos não são suficientes: register spilling na stack• Elimina quais quer ganhos de desempenho

Page 32: Optimização do Desempenho: Técnicas Dependentes da Máquina

Saltos Condicionais

• Previsão de saltos condicionais para manter o pipeline ocupado

• Nos processadores modernos uma previsão errada implica custos elevados– Pentium III: ≈ 14 ciclos do relógio

• Os saltos condicionais podem, em algumas situações, ser evitados pelo compilador com ajuda do programador

32

Page 33: Optimização do Desempenho: Técnicas Dependentes da Máquina

Saltos Condicionais

Exemplo: Calcular o máximo de 2 valores

33

int max(int x, int y){ if (x < y) return y; else return x;}

movl 12(%ebp),%edx # Get ymovl 8(%ebp),%eax # ret val=xcmpl %edx,%eax # rval-yjge L11 # skip when >=movl %edx,%eax # ret val=y

L11:

Pentium III:• 14 ciclos se previsão correcta• 29 ciclos se previsão errada

Page 34: Optimização do Desempenho: Técnicas Dependentes da Máquina

mov condicional

34

– Adicionadas à microarquitectura P6 (PentiumPro)– cmovXXl %edx, %eax

• Se condição XX verdadeira, copia %edx para %eax• Não há saltos condicionais• Corresponde a uma única µoperação

– Sem as opções correctas o compilador pode não usar esta optimização:

• Compila para o 386– Desempenho

• 14 ciclos

movl 12(%ebp),%edx # Get ymovl 8(%ebp),%eax # ret val=xcmpl %edx, %eax # ret val-y

cmovll %edx,%eax # If <, ret val=y

int max(int x, int y){ return(x < y) ? y:x;}