TDC2013 Otimizando-C

49
Globalcode – Open4education Otimizando-C

description

Apresentação no TDC2013 - Florianópolis da trilha Mobile e Embedded (25/05/2013). Apresenta algumas dicas, técnicas e sugestões de como melhorar o processamento e uso de memória no código.

Transcript of TDC2013 Otimizando-C

Page 1: TDC2013 Otimizando-C

Globalcode – Open4education

Otimizando-C

Page 2: TDC2013 Otimizando-C

Globalcode – Open4education

Sumário

whoami

Otimização?! WTF!?

#define X const

Aritmética

Condições

Laços

Page 3: TDC2013 Otimizando-C

Globalcode – Open4education

Sumário (2)

Alocação

Parâmetros

rand()

Fronteira final

Bora otimizar então! #sqn

Page 4: TDC2013 Otimizando-C

Globalcode – Open4education

whoami

Osmar da Cunha FilhoFormado em Engenharia de Computação (UNIVALI)

Pós-graduado em Desenvolvimento de Produtos Eletrônicos (IFSC)

Coordenador de desenvolvimento de Hardware (Specto)

Professor nos cursos de Ciências da Computação (IES) e Engenharia Civil (IES)

Page 5: TDC2013 Otimizando-C

Globalcode – Open4education

Otimização!? WTF!?Otimizar

v.t.d. Ocasionar circunstâncias mais proveitosas para; retirar o que há de melhor em; aprimorar, melhorar: otimizar o desenvolvimento do produto; otimizar as condições de trabalho.

Dar a (algo, uma máquina, uma empresa) um rendimento ótimo, criando-lhe as condições mais favoráveis ou tirando (dele ou dela) o melhor partido possível; tornar (algo) ótimo ou ideal.

Estatística. Instituir o maior valor de uma grandeza.

Informática. Aperfeiçoar um programa para que o mesmo seja melhor utilizado ou funcione mais rapidamente.

Fonte: http://www.dicio.com.br/otimizar/

Page 6: TDC2013 Otimizando-C

Globalcode – Open4education

Otimização!? WTF!?

Melhorar performance

Diminuir consumo de recursosTempo

ProcessamentoEspaço

Memória

Page 7: TDC2013 Otimizando-C

Globalcode – Open4education

Otimização!? WTF!?

TradeoffProcessamento

Memória

Legibilidade

Complexidade

Page 8: TDC2013 Otimizando-C

Globalcode – Open4education

#define X const

Macros (#define) são resolvidas em tempo de compilação

Consts NEM SEMPRE são resolvidas em tempo de compilação

Alguns compiladores as traduzem para #defines

#defines são substituídas à medida que o código vai sendo lido pelo compilador

Consts geram código e consomem memória de programa

Page 9: TDC2013 Otimizando-C

Globalcode – Open4education

AritméticaMultiplicação/Divisão

Potência de dois2, 4, 8, 16, 32, 64, 128, 256

21, 22, 23, 24, 25, 26, 27, 28

Multiplicações/Divisões por potências de dois são rotações de bits

Rotações de bits são operações lógicas!

Operações lógicas são mais rápidas que aritméticas porque não possuem sinal!

Page 10: TDC2013 Otimizando-C

Globalcode – Open4education

AritméticaMultiplicação/Divisão

Multiplicaçãox << 1

x << 2

x << 3

x << 4

Divisãox >> 1

x >> 2

x >> 3

x >> 4

x * 21

x * 22

x * 23

x * 24

x / 21

x / 22

x / 23

x / 24

Page 11: TDC2013 Otimizando-C

Globalcode – Open4education

CondiçõesCurto-circuito

Curto-circuito ou avaliação preguiçosa (lazy evaluation)

Sempre em um if de múltiplas condições simultâneas, colocar a condição mais fácil de ser testada antes, de forma que as condições seguintes nem cheguem a ser testadas

A ideia é sair o quanto antes

Page 12: TDC2013 Otimizando-C

Globalcode – Open4education

CondiçõesCurto-circuito

if ( a < 0 && funcaoQueCalcula() > 10)

if ( !b && j > 10)

Page 13: TDC2013 Otimizando-C

Globalcode – Open4education

CondiçõesEliminar “senão”

Pode ser menos custoso executar uma operação e desfazê-la com próprio if

Elimina algumas instruções referentes ao um salto condicional

Page 14: TDC2013 Otimizando-C

Globalcode – Open4education

CondiçõesEliminar “senão”// Exemplo antesif (condicao) { executaCasoSe();}else { executaCasoSenao();}

// Exemplo depoisexecutaCasoSenao();if (condicao) { desfazCasoSenao(); executaCasoSe()}

// Exemplo antesif (condicao) { variavel = 0;}else { variavel++;}

// Exemplo depoisvariavel++;if (condicao) { variavel = 0;

}

Page 15: TDC2013 Otimizando-C

Globalcode – Open4education

LaçosLoop jamming

Loop jamming

Agrupar códigos que irão repetir em um laço só

Principalmente se forem repetidas pela mesma quantidade de vezes

Page 16: TDC2013 Otimizando-C

Globalcode – Open4education

LaçosLoop jamming// Exemplo antesfor ( i = 0; i < 100; i++ ){ fazAlgo();}

for ( i = 0; i < 100; i++ ){ fazOutraCoisa();}

// Exemplo depoisfor (i = 0; i < 100; i++ ){ fazAlgo(); fazOutraCoisa();}

Page 17: TDC2013 Otimizando-C

Globalcode – Open4education

Laços++ X --

Em vez de contadores progressivos até o limite máximo, utilizar contadores regressivos terminando em zero

Algumas arquiteturas possuem instruções que testam condição de zero após decrementar

Page 18: TDC2013 Otimizando-C

Globalcode – Open4education

Laços++ X --// Incremementandofor ( i = 0; i < 100 ; i++)

// O laco tem que comparar com um valor != 0i – 100 == 0 ?i++ e continua

// Decrementandofor ( i = 100; i-- ; )

// O laco tem que testar uma flag de zero da ULAi == 0 ?i-- e continua

Page 19: TDC2013 Otimizando-C

Globalcode – Open4education

Para não chamar a mesma função inúmeras vezes, passando como parâmetro um contador, criar uma função com o contador internamente

LaçosContador como parâmetro

// Calcula passando parametro i (antes)for (i = 0; i < 100; i++) { calcula(x,i); }

// Modificando a funcao para calcular dentro do laco (depois)void calcula (x) { for(i = 0; i < 100; i++) { //calcula no laço }}

Page 20: TDC2013 Otimizando-C

Globalcode – Open4education

LaçosFim

O laço precisa mesmo ir até o final?

Ele pode sair antes e retornar o valor?

Por exemplo em uma pesquisa de elementos!

for (i = 0 ; i < 100 ; i++ ) { if (arrayExemplo[i] == 100 ) { encontrado = i; break; }}

Page 21: TDC2013 Otimizando-C

Globalcode – Open4education

LaçosLoop unrolling

Desenrolar laços de poucas repetições

O compilador não precisa definir a estrutura para repetição nem calcular índices

// Antesfor ( i = 0 ; i < 3; i++ ) { arrayExemplo[i] = 2*i;}

// DepoisarrayExemplo[0] = 0;arrayExemplo[1] = 2;arrayExemplo[2] = 4;

Page 22: TDC2013 Otimizando-C

Globalcode – Open4education

LaçosIterativo X Recursivo

Preferir algoritmos iterativos a recursivosPode causar estouro de pilha

Aumenta a passagem de parâmetros

Cuidado ao chamar funções no tratamento de interrupções!

Page 23: TDC2013 Otimizando-C

Globalcode – Open4education

AlocaçãoLocal X Global

O compilador pode alocar variáveis locais diretamente em registrador ou na pilha

Variáveis globais vão para a memória (RAM) e por isso pode ser necessário mais bytes de endereço para acessá-la

Page 24: TDC2013 Otimizando-C

Globalcode – Open4education

AlocaçãoTipos de dados - Tamanho

Utilizar o tipo mais adequado ao problemachar, int, long?

float, double?

Operações com ponto flutuante demoram mais que operações em tipos inteiros

Consultar a unidade de ponto flutuante (FPU)!

Page 25: TDC2013 Otimizando-C

Globalcode – Open4education

AlocaçãoTamanho

Na dúvida, use a bitagem da arquitetura!

Em PCs x86, int é mais rápido que char e shortChar e short precisam ser reduzidos!

Int é padrão da arquitetura (seja ela 32 ou 64 bits)!

Em microcontroladores 8 bits, char é mais rápidoUnsigned char é mais rápido ainda

Page 26: TDC2013 Otimizando-C

Globalcode – Open4education

Alocaçãosigned X unsigned

Tipos sem sinal são mais rápidosunsigned char, unsigned int, unsigned long

Tipos com sinal passam por circuitos a mais na ULA para estender o sinal

Número sem sinal: bit mais significativo é zero

Número com sinal: bit mais significativo é um

Page 27: TDC2013 Otimizando-C

Globalcode – Open4education

(Extensão de sinal)

Complemento de dois

-1281000 0000

-641100 0000

+640011 1111

+1270111 1111

2551111 1111

1270111 1111

630011 1111

310001 1111

Page 28: TDC2013 Otimizando-C

Globalcode – Open4education

AlocaçãoInicialização X Atribuição

É preferível inicializar já com o valor do que apenas declarar e inicializar depois

Ao inicializar na declaração, não há dois distintos momentos (alocação e atribuição), ao alocar o compilador já atribui o valor!

Page 29: TDC2013 Otimizando-C

Globalcode – Open4education

AlocaçãoInicialização X Atribuição// InicializacaoTipo variavel = valor;

// Declaracao e atribuicaoTipo variavel;...variavel = valor;

Page 30: TDC2013 Otimizando-C

Globalcode – Open4education

AlocaçãoArrays X Ponteiros

Em vez de usar arrays e índices, utilizar ponteiros!

Utilizando arrays, para acessar o índice nLer o endereço base do array

Ler n

Somar endereço base com n

Acessar o endereço calculado

Page 31: TDC2013 Otimizando-C

Globalcode – Open4education

AlocaçãoArrays X Ponteiros

Usando ponteiros:Apontar o ponteiro para o início do array

Somar o índice ao ponteiroAritmética de ponteiros! :D

Recalcular os índices deixa de ser repetida a cada iteração

Para varrer listas (uso comum), o ponteiro é incrementado em somente uma unidade (INC)

Page 32: TDC2013 Otimizando-C

Globalcode – Open4education

AlocaçãoArrays X Ponteiros// Antesint arrayTeste[100];

for (i = 0; i < 100; i++){ arrayTeste[i] = 0;}

// Depoisint arrayTeste[100];int *ponteiroArray;

ponteiroArray = &arrayTeste[0];

for (i = 0; i < 100; i++) { *ponteiroArray = 0; ponteiroArray++;}

Page 33: TDC2013 Otimizando-C

Globalcode – Open4education

AlocaçãoArrays multidimensionais

Localidade de referênciaValor ou local de armazenamento frequentemente acessado

Localidade de referência espacialLocais de armazenamento próximos

Arrays multidmensionais serão alocados em uma memória unidimensional

Page 34: TDC2013 Otimizando-C

Globalcode – Open4education

AlocaçãoArrays multidimensionais

Atenção à ordem dos índices!

Acessar: arrayTeste [ i ][ j ]

arrayTeste [ i ] [ j + 1]é melhor que:

arrayTeste [ i + 1 ] [ j ]

Page 35: TDC2013 Otimizando-C

Globalcode – Open4education

AlocaçãoAlinhamento (padding)

// Cabe em 20 bytes:struct exemplo { int a; char b; int c; char d; int e;}

// Cabe em 16 bytes:struct exemplo { int a; int c; int e; char b; char d;}

Alinhar o tipo a potências de 2!

Page 36: TDC2013 Otimizando-C

Globalcode – Open4education

AlocaçãoCampos de bits (bitfields)

Para otimizar uso de memória para armazenar um valor booleano, pode-se utilizar campos de bits

struct campoDeBits { unsigned bit0: 1; unsigned bit1: 1; unsigned bit2: 1; unsigned bit3: 1; unsigned bit4: 1; unsigned bit5: 1; unsigned bit6: 1; unsigned bit7: 1;}

Page 37: TDC2013 Otimizando-C

Globalcode – Open4education

AlocaçãoCampos de bits (bitfields)

Alguns cuidados com os campos de bits:Os bits não são endereçáveis diretamente (pelo operador &), somente pela struct (no exemplo, campoDeBits.bit0)

Custa mais processamento ler um bit do que um unsigned char

Exige operações de teste bit a bit

Page 38: TDC2013 Otimizando-C

Globalcode – Open4education

Parâmetros

Dependendo da arquitetura, os primeiros parâmetros (4 para x86) são passados por registradores

Os parâmetros seguintes são passados pela pilha

Ou seja, além do quarto parâmetro, custa ainda mais acessar os parâmetros

Operações de acesso à pilha

Page 39: TDC2013 Otimizando-C

Globalcode – Open4education

Parâmetros

É preferível passar structs por referência em vez de por valor

Assim não há a cópia da struct toda para registradores/pilha

Page 40: TDC2013 Otimizando-C

Globalcode – Open4education

Parâmetros

Diminuir a quantidade de parâmetros utilizando variáveis globais

Muitas funções precisando de um mesmo dado

Evita estouros de pilha!

Page 41: TDC2013 Otimizando-C

Globalcode – Open4education

Parâmetros

Utilizar referência em vez de ponteirosReferências nunca são NULL

Código mais limpo (sem inúmeros *)

Page 42: TDC2013 Otimizando-C

Globalcode – Open4education

rand()F**K OPTIMIZING

Quando não se quer que o compilador otimize uma variável, basta declará-la como volatile

volatile unsigned char variavel;

Útil em casos que a variável é compartilhadaInterrupções

Timers

Threads

Page 43: TDC2013 Otimizando-C

Globalcode – Open4education

rand()Isso está otimiza(n)do?

Conferir o código gerado

Assembly listing

Arquivos intermediários de compilação.MAP

.LST

.S

Page 44: TDC2013 Otimizando-C

Globalcode – Open4education

Fronteira final!?

Otimização pelo compilador

Análise de algoritmo (big-O)

Buscar outros algoritmos

Otimizar em Assembly.

Page 45: TDC2013 Otimizando-C

Globalcode – Open4education

Bora otimizar, então! #sqn

Não adianta otimizar o que ESTÁ ERRADO!

Primeiro preocupar-se com a corretude

Garantir a legibilidade do código

É tão necessário transformar tudo em ponteiros em #defines?

Page 46: TDC2013 Otimizando-C

Globalcode – Open4education

Bora otimizar, então! #sqn

Donald Knuthpremature optimization is the root of all evil

Tio BenWith great powers come great responsabilities

Page 47: TDC2013 Otimizando-C

Globalcode – Open4education

Perguntas?

Dúvidas?

Reclamações?

Sugestões?

Questões existenciais?

Page 48: TDC2013 Otimizando-C

Globalcode – Open4education

Osmar da Cunha Filho

@oooosmar (4 letras “o”)

Page 49: TDC2013 Otimizando-C

Globalcode – Open4education

Obrigado!

:D