Módulo IV Técnicas de Otimização I Otimizações Gerais usando uma Linguagem Compilada.

44
Módulo IV Técnicas de Otimização I Otimizações Gerais usando uma Linguagem Compilada

Transcript of Módulo IV Técnicas de Otimização I Otimizações Gerais usando uma Linguagem Compilada.

Page 1: Módulo IV Técnicas de Otimização I Otimizações Gerais usando uma Linguagem Compilada.

Módulo IV

Técnicas de Otimização I

Otimizações Gerais usando uma Linguagem Compilada

Page 2: Módulo IV Técnicas de Otimização I Otimizações Gerais usando uma Linguagem Compilada.

Computação de Constantes no Laço

LoopInvar(int size,int step,int ratio)

{ int gradient;

for ( i = 0; i < size/step; i += step ) { gradient = step*ratio; sort[i] *= gradient; }

return; }

Este cálculo é uma Este cálculo é uma constante, mas o constante, mas o

compilador o trata como compilador o trata como uma equação qualquer, uma equação qualquer, processando-a a cada processando-a a cada

iteração no laçoiteração no laço

O compilador O compilador não consegue não consegue otimizar esta otimizar esta

operação, assim operação, assim temos um valor temos um valor

constante sendo constante sendo calculado calculado

sempre e sem sempre e sem necessidadenecessidade

Page 3: Módulo IV Técnicas de Otimização I Otimizações Gerais usando uma Linguagem Compilada.

Computação de Constantes em Laços

LoopInvar(int size,int step,int ratio)

{ int gradient; int limit;

gradient = step * ratio; limit = size/step;

for ( i = 0; i < limit; i += step ) { sort[i] *= gradient; }

return; }

Uso de variáveis Uso de variáveis temporárias pode temporárias pode

ajudar o ajudar o compilador na compilador na otimização do otimização do

códigocódigo

Page 4: Módulo IV Técnicas de Otimização I Otimizações Gerais usando uma Linguagem Compilada.

Computação de Constantes em Laços: Desvios (Branches)

InvarBranch(int size, int mode, int offset){

for (int i = 0; i < size; i += 1)

if (mode & DIV_OFST)

data[i] /= offset;

else

data[i] += offset;

return;

}

Desvios no código não Desvios no código não combinam com combinam com

desempenho, então desempenho, então por que fazer um por que fazer um

desvio a cada passo desvio a cada passo dentro do laço? dentro do laço?

O valor de O valor de mode mode pode mudar a pode mudar a cada chamada dessa função, mas cada chamada dessa função, mas

não dentro do laço. Uma vez não dentro do laço. Uma vez dentro do laço, toda iteração é dentro do laço, toda iteração é

igual, não precisamos do desvioigual, não precisamos do desvio

Page 5: Módulo IV Técnicas de Otimização I Otimizações Gerais usando uma Linguagem Compilada.

Computação de Constantes em Laços: Desvios (Branches)

InvarBranch(int size, int mode, int offset) {

if (mode & DIV_OFST)

for (i = 0; i < size; i += 1)

data[i] /= offset;

else

for (i = 0; i < size; i += 1)

data[i] += offset;

return;

}

Mais código, Mais código, menos intuitivo menos intuitivo e mais rápido!e mais rápido!

Page 6: Módulo IV Técnicas de Otimização I Otimizações Gerais usando uma Linguagem Compilada.

Laços com Contagem: Decrementando em um Laço

CountDown(int size) {

int i;

for (i = 0; i < size; i++)

array[i] = 0;

return;

}

É mais simples para É mais simples para o processador o processador

comparar a variável i comparar a variável i com zero!com zero!

Page 7: Módulo IV Técnicas de Otimização I Otimizações Gerais usando uma Linguagem Compilada.

Laços com Contagem: Um Solução

CountDown(int size) {

int i;

for (i = size-1; i >= 0; i--)

array[i] = 0;

return;

}

A comparação com A comparação com zero é mais eficiente, zero é mais eficiente,

no decremento ao no decremento ao passar por zero o passar por zero o

indicador de zero do indicador de zero do processador é ativado, processador é ativado, nenhuma comparação nenhuma comparação

é necessária com outro é necessária com outro valor para resolver valor para resolver

esta condiçãoesta condição

Page 8: Módulo IV Técnicas de Otimização I Otimizações Gerais usando uma Linguagem Compilada.

Agrupando Variáveis

int ClusterVar( int offset, int ratio, int size) {

int i, gradient, delta;

gradient = offset * ratio;

for (i = 0; i < size; i++)

array[i] = 0;

delta = offset – ratio;

return delta + gradiente;

}

deltadelta também é também é calculado pelos calculado pelos

valores de valores de offsetoffset e e ratioratio

gradientgradient é calculado é calculado pelos valores de pelos valores de offsetoffset

e e ratioratio

Page 9: Módulo IV Técnicas de Otimização I Otimizações Gerais usando uma Linguagem Compilada.

Agrupando Variáveis de maneira Eficienteint ClusterVar(int offset, int ratio, int size){

int i, gradient, delta;

for ( i = 0; i < size; i++)

array[i] = 0;

gradient = offset * ratio;

delta = offset – ratio;

return delta + gradiente;

}

A utilização agrupada A utilização agrupada das variáveis facilita a das variáveis facilita a tarefa de otimização tarefa de otimização

ao compiladorao compilador

Page 10: Módulo IV Técnicas de Otimização I Otimizações Gerais usando uma Linguagem Compilada.

Interpretando e Simplificando uma Função

int IsEven(int value) {

int result;

result = value / 2;

if (result * 2 == value)

return 1;

else

return 0;

}

O objetivo desta O objetivo desta função é determinar função é determinar se o parâmetro é par. se o parâmetro é par.

Se for retorna 1. Se for retorna 1.

Page 11: Módulo IV Técnicas de Otimização I Otimizações Gerais usando uma Linguagem Compilada.

Uma Solução mais Simples

int IsEven(int value) {

return !(value & 0x1);

}Toda representação Toda representação

binária de um número binária de um número par termina com zero e par termina com zero e esta função utiliza esse esta função utiliza esse

fatofato

Page 12: Módulo IV Técnicas de Otimização I Otimizações Gerais usando uma Linguagem Compilada.

Simplificando ainda mais

__inline int IsEven(int value) {

return (~value)&0x1;

}Agora a função é tão Agora a função é tão simples que devemos simples que devemos considerar o uso de considerar o uso de

inline ou macroinline ou macro

Page 13: Módulo IV Técnicas de Otimização I Otimizações Gerais usando uma Linguagem Compilada.

Inlining Otimização muito oportuna para eliminar a sobrecarga

da chamada e do retorno de uma funçãoint IsEven(int value)

{ int result;

result = value / 2;

if ( result * 2 == value ) { return 1; } else { return 0; } }

int IsEven(int value)

{ return (~value)&0x1; }

__inline int IsEven(int value)

{ return (~value)&0x1; }

Simplificando

Usando __inline na função

Page 14: Módulo IV Técnicas de Otimização I Otimizações Gerais usando uma Linguagem Compilada.

Ponteiros: Indexação

BasePtr(int *ptr, int *cmask, int section, int limit) {

int i;

for (i = 0; i < limit; i++) {

*(ptr + section * secsize + i) &= *cmask;

cmask++;

}

return;

}

Uma parte do cálculo Uma parte do cálculo deste ponteiro não deste ponteiro não varia dentro deste varia dentro deste

laço, logo é possível laço, logo é possível implementações mais implementações mais

eficienteseficientes

Page 15: Módulo IV Técnicas de Otimização I Otimizações Gerais usando uma Linguagem Compilada.

Ponteiros: Indexação

BasePtr(int *ptr, int *cmask, int section, int limit) {

int *auxptr, i;

auxptr = ptr + section * secsize;

for (i = 0; i < limit; i++) {

*(auxptr + i ) &= *cmask;

cmask++;

}

return;

}

Calculando a parte do Calculando a parte do ponteiro que é ponteiro que é

independente de independente de qualquer valor do laço, qualquer valor do laço,

resta uma parte de resta uma parte de cálculo bem mais cálculo bem mais simples para ser simples para ser

executada dentro dele.executada dentro dele.

Poderíamos ir Poderíamos ir além dessa além dessa otimização?otimização?

Page 16: Módulo IV Técnicas de Otimização I Otimizações Gerais usando uma Linguagem Compilada.

Ponteiros: Mais otimizaçõesint BasePtr(int *ptr,int *cmask, int section,int limit)

{

int i;

int *auxptr;

auxptr = ptr + section * secsize;

auxptr += limit – 1;

cmask += limit – 1;

for ( i = limit - 1; i >=; 0 i-- )

*(auxptr--) &= *(cmask--);

return;

}

Ajustamos nossos Ajustamos nossos ponteiros para o último ponteiros para o último

elemento, assim podemos elemento, assim podemos contar decrementandocontar decrementando

Fazer o laço decrementar Fazer o laço decrementar até zero tira vantagem do até zero tira vantagem do conjunto de instruções do conjunto de instruções do

processador ARM processador ARM

Pós-decremento dos Pós-decremento dos ponteiros torna mais fácil ponteiros torna mais fácil

para o compilador o uso de para o compilador o uso de instruções de load/store instruções de load/store

com pós-decremento.com pós-decremento.

Page 17: Módulo IV Técnicas de Otimização I Otimizações Gerais usando uma Linguagem Compilada.

Redução de Desvios (Branches)Void MultBranch(void) {

//iniciação de mask e shiftbits

if (mode & TRANSPNT ) {

mask = 0x0110;

shiftbits = 4;

} else {

mask = 0x1100;

shiftbits = 8;

}

//ajustando limite

limit = 5;

if (mode & TRANSPNT) limit = 9;

...

Existe Existe alguma alguma

maneira de maneira de reduzirmos reduzirmos os ifs e os os ifs e os desvio?desvio?

Iniciação de Iniciação de shiftbits e shiftbits e

maskmask

Iniciação Iniciação de limitde limit

Page 18: Módulo IV Técnicas de Otimização I Otimizações Gerais usando uma Linguagem Compilada.

Redução de Desvios (Branches)void MultBranch(void) {

//iniciação de mask, shiftbits e limit

if (mode & TRANSPNT ) {

limit = 5;

mask = 0x0110;

shiftbits = 4;

} else {

limit = 9;

mask = 0x1100;

shiftbits = 8;

}

...

Evitar Evitar desvios em desvios em um código é um código é uma prática uma prática saudável!saudável!

Iniciação de shiftbits e Iniciação de shiftbits e mask, além de alterar o mask, além de alterar o valor de limit, tudo em valor de limit, tudo em

um só if.um só if.

Page 19: Módulo IV Técnicas de Otimização I Otimizações Gerais usando uma Linguagem Compilada.

Localidade de Referência de Memóriaint Image[128][128];

void ImageFilter(void) {

int i, j, k, sum;

// Percorre as colunas

for ( i = 0; i < 128; i++ ) {

sum = 0;

for ( j = 0; j < 128; j++ ) {

sum = 0;

for ( k = 0; k < 8; k++ ) {

sum += Image[j][i] * filter[j];

}

Image[j][i] = sum;

}

}

}

// Percorre as linhas

for ( i = 0; i < 128; i++ )

Estamos percorrendo a Estamos percorrendo a matriz imagem pela matriz imagem pela coluna, embora ela coluna, embora ela seja armazenada na seja armazenada na

memória em função de memória em função de suas linhas suas linhas

Pensando como os dados são Pensando como os dados são armazenados na cache vemos armazenados na cache vemos

que essa não é uma boa maneira que essa não é uma boa maneira de se trabalhar com um array...de se trabalhar com um array...

Page 20: Módulo IV Técnicas de Otimização I Otimizações Gerais usando uma Linguagem Compilada.

Localidade de Referência de Memória

TransmuteArray(Image,0);

for ( i = 0; i < 128; i++ ) {

sum = 0;

for ( j = 0; j < 128; j++ ) {

sum = 0;

for ( k = 0; k < 8; k++ )

sum += Image[i][j] * filter[j];

Image[i][j] = sum;

}

}

TransmuteArray(Image,1);

Essa é uma maneira Essa é uma maneira muito mais eficiente de muito mais eficiente de se percorrer a matriz se percorrer a matriz

Reordene a matriz Reordene a matriz antes de processá-la antes de processá-la de maneira a transpor de maneira a transpor

as linhas pelas as linhas pelas colunas. Depois re-colunas. Depois re-

processe novamente a processe novamente a matrizmatriz

Page 21: Módulo IV Técnicas de Otimização I Otimizações Gerais usando uma Linguagem Compilada.

Uso Eficiente de Bibliotecasvoid OutputMethod(HANDLE JavaSource, HANDLE JavaBin)

{

unsigned char BCode;

int EndMethod;

EndMethod = 0;

while( !EndMethod )

{

EndMethod =

GenByteCode(JavaSource, &BCode);

write(JavaBin,&BCode,1);

}

}

A rotina A rotina writewrite é é chamada para todos os chamada para todos os

bytecodes pela JITbytecodes pela JIT

A função A função writewrite realiza realiza várias verificações no várias verificações no handle do arquivo e no handle do arquivo e no seu estado (e faz isso a seu estado (e faz isso a

cada chamada da cada chamada da função) Ela pode função) Ela pode

armazenar ou não as armazenar ou não as escritas internamenteescritas internamente

Page 22: Módulo IV Técnicas de Otimização I Otimizações Gerais usando uma Linguagem Compilada.

Uso Eficiente de Bibliotecas - Otimização#define BSIZE 128

void OutputMethod(

HANDLE JavaSource,

HANDLE JavaBin)

{

unsigned char *pBuff;

unsigned char buffer[BSIZE];

int BuffLeft;

int EndMethod;

/* write out bytecodes till

we reach the end of method */

EndMethod = 0;

pBuff = buffer;

BuffLeft = BSIZE;

while( !EndMethod )

{

EndMethod = GenByteCode(JavaSource,

&BCode);

*pBuff++ = BCode;

if (BuffLeft-- <= 0 )

{

write(JavaBin,buffer,BSIZE);

BuffLeft = BSIZE;

pBuff = buffer;

}

} // end of while…

if ( BuffLeft < BSIZE )

{

write(JavaBin,buffer,

BSIZE – BuffLeft);

}

} // end of function OutputMethod

Page 23: Módulo IV Técnicas de Otimização I Otimizações Gerais usando uma Linguagem Compilada.

EndMethod = GenByteCode(JavaSource,

&BCode);

*pBuff++ = BCode;

if (BuffLeft-- <= 0 )

{

write(JavaBin,buffer,BSIZE);

BuffLeft = BSIZE;

pBuff = buffer;

}

} // end of while…

if ( BuffLeft < BSIZE )

{

write(JavaBin,buffer,

BSIZE – BuffLeft);

}

} // end of function OutputMethod

Uso Eficiente de Bibliotecas - OtimizaçãoAgora a função Agora a função writewrite é é

usada muito mais usada muito mais eficientementeeficientemente

Veja que a variável Veja que a variável BuffLeft é decrementada BuffLeft é decrementada

até Zeroaté Zero

Observe esse ponteiro Observe esse ponteiro pós-incrementado: Uma pós-incrementado: Uma

única instrução assembly única instrução assembly STR é capaz de STR é capaz de

armazenar e atualizar o armazenar e atualizar o ponteiroponteiro

Page 24: Módulo IV Técnicas de Otimização I Otimizações Gerais usando uma Linguagem Compilada.

Uso Eficiente de Bibliotecas

Use cada função com mais eficiência, pois fazer menos chamadas implica: Menor sobrecarga da chamada da função Menor sobrecarga de verificação de erros Menos acessos a dispositivos físicos

Compreenda as limitações dos dispositivos Eficiência na escrita em Flash Limitação da Biblioteca

Page 25: Módulo IV Técnicas de Otimização I Otimizações Gerais usando uma Linguagem Compilada.

Desenrolamento de Laço

void LoopUnRoll(int limit,int translate) {

int i;

for ( i = 0; i < limit, i++ ) {

array[i] += translate;

}

}

A sobrecarga para A sobrecarga para percorrer o laço prejudica percorrer o laço prejudica

o desempenho!o desempenho!

De 2 a 3 instruções a De 2 a 3 instruções a cada iteração do laço do cada iteração do laço do

forfor

De 3 a 4 instruções para De 3 a 4 instruções para executar o corpo do laçoexecutar o corpo do laço

Page 26: Módulo IV Técnicas de Otimização I Otimizações Gerais usando uma Linguagem Compilada.

Implementação do Desenrolamento de Laçovoid LoopUnRoll(int limit,int translate) {

int i;

for ( i = 0; i < limit, i += 4 ) {

array[i] += translate;

array[i + 1] += translate;

array[i + 2] += translate;

array[i + 3] += translate;

}

}

E a escrita consegutiva para dados contíguos pode E a escrita consegutiva para dados contíguos pode aproveitar mais uma característica do processador aproveitar mais uma característica do processador

XScale: Write CoalescingXScale: Write Coalescing

De 2 a 3 instruções a cada De 2 a 3 instruções a cada iteração do laço do iteração do laço do forfor

De 12 a 16 instruções para De 12 a 16 instruções para executar o corpo do laçoexecutar o corpo do laço

Page 27: Módulo IV Técnicas de Otimização I Otimizações Gerais usando uma Linguagem Compilada.

Usando Comentários no Código como Técnica de Medição

Se você gostaria de saber o quanto uma linha ou pedaço de código contribuem para o desempenho de execução de uma função... Considere comentar a linha ou bloco de código a ser

analisado. Tenha certeza que o código ao redor não é

demasiadamente sem importância a ponto do otimizador do compilador simplesmente descartá-lo.

Substitua algo muito simples que o compilador não possa otimizar.

Page 28: Módulo IV Técnicas de Otimização I Otimizações Gerais usando uma Linguagem Compilada.

Usando Comentários no Código como Técnica de Medição

Sx = 0;

for ( col = 0; col < numCols; col++) {

for ( row = 3; row < (numRows – 3);row++) {

ploc1 = in + (row*numCols + col);

ploc2 = ploc1 + 1;

Kr = ((*(ploc1-adj3) ...

Ks = ((*(ploc2 – adj3)....

}

if (Kr < 0 ) Kr = -Kr;

if (Ks < 0 ) Ks = -Ks;

// Sx += (S16Word)sqrt( Kr +Ks );

Sx += Kr + Ks;

}

Exemplo:Exemplo:

Comente a linha que Comente a linha que contém sqrtcontém sqrt

Substitua esta linha Substitua esta linha com algo que evite que com algo que evite que

o compilador altere o compilador altere drasticamente o código drasticamente o código

compilado. compilado.

Page 29: Módulo IV Técnicas de Otimização I Otimizações Gerais usando uma Linguagem Compilada.

Módulo IV

Técnicas de Otimização II

Page 30: Módulo IV Técnicas de Otimização I Otimizações Gerais usando uma Linguagem Compilada.

O que é PreLoad? PreLoad coloca o dado a ser utilizado pelo

processador dentro da memória cache.

Suporte na extensão ARM .v5 DSP do compilador Microsoft na versão 4.0

Dado um endereço, o PreLoad inicia a carga dos 32 bytes da memória que inclui o endereço para a memória cache.

Page 31: Módulo IV Técnicas de Otimização I Otimizações Gerais usando uma Linguagem Compilada.

O que é PreLoad? Os 5 bits inferiores de endereço são ignorados, desde

que as linhas da cache são alinhadas em 32 bytes.

Não há o conceito de largura. Não se pode carregar o conteúdo de um valor de tamanho maior que 32 bytes usando PreLoad, pois ele ultrapassa o tamanho da linha de cache (32 bytes).

Leitura sem atribuição para um registrador de destino, não ocupa o pend buffer.

Endereços inválidos de memória não geram exceções, são ignorados.

Page 32: Módulo IV Técnicas de Otimização I Otimizações Gerais usando uma Linguagem Compilada.

Quando o PreLoad é eficiente?Quando o processamento de dados contíguos são

repetido dentro de um laço

Quando o endereço de elementos em uma iteração posterior são facilmente determinados

O dado provavelmente não está na cache É muito grande em bytes para caber inteiro na cache

O dado não foi recentemente gerado ou preparado em outro estágio

Page 33: Módulo IV Técnicas de Otimização I Otimizações Gerais usando uma Linguagem Compilada.

Por que usar PreLoad?Buscar um dado na memória é uma operação cara

em qualquer tipo de processador

Dados presentes na memória cache são manipulados mais rapidamente

PreLoad busca o dado e o coloca na cache. Se bem usado, pode economizar tempo do processador na utilização de um dado da memória

Page 34: Módulo IV Técnicas de Otimização I Otimizações Gerais usando uma Linguagem Compilada.

PreLoad irá ajudar?

Utilize o VTune

Procure por funções onde há uma taxa alta de “cache miss”

Taxa alta de Cache Miss

Cache Miss = 28,76%

Page 35: Módulo IV Técnicas de Otimização I Otimizações Gerais usando uma Linguagem Compilada.

Alterações no Código para Incrementar a Eficiência de PreLoad

Otimize o uso da Cache Os dados devem preferencialmente estar próximos na

memória

Use dados em posições contíguas de memória

Para listas encadeadas, onde todos os elementos

estão “embaralhados” Use um ponteiro especial que aponta para ‘n’

elementos a frente

Page 36: Módulo IV Técnicas de Otimização I Otimizações Gerais usando uma Linguagem Compilada.

Alterações no Código para Incrementar a Eficiência de PreLoad

Para matrizes de estruturas onde somente alguns

membros são usados em algum laço Faça duas matrizes de estruturas, com os membros mais

usados em uma estrutura e o resto em outra matriz

Permite que as estruturas com os dados usados mais

freqüentemente fiquem contidas em uma única linha da

memória cache

Page 37: Módulo IV Técnicas de Otimização I Otimizações Gerais usando uma Linguagem Compilada.

Ajustando o PreLoadQuantos dados devem ser colocados na cache por

“antecipação de uso”?

Tente usar o método empírico Depende da complexidade do código executado no laço

entre sucessivas execuções do PreLoad

O PreLoad deve carregar os dados na cache com 40 a 80 clocks de instrução antes de usá-los

Faça do valor de antecipação do PreLoad uma constante que possa ser alterada no seu código

Page 38: Módulo IV Técnicas de Otimização I Otimizações Gerais usando uma Linguagem Compilada.

Eficiência máxima do PreLoad Melhor se houve apenas um PreLoad por linha de cache (Tempo do processamento por item de dado) * (Número

de itens por linha de cache) deve ser aproximadamente tempo de acesso externo

Senão, faça PreLoad no número apropriadode linhas de cache

Não exceda 4 linhascom PreLoad de umavez

Linha de cacheVia 31

DadosEnder.

Linha de cacheVia 1

Linha de cacheVia 0

32 conjuntos

Page 39: Módulo IV Técnicas de Otimização I Otimizações Gerais usando uma Linguagem Compilada.

Eficiência máxima do PreLoad

Considere que outros dados também receberão acesso (leitura e escrita à memória). Lembre-se do fill buffer.

A taxa de alimentação deve ser igual a taxa de consumo Se o tempo de processamento por uma linha de cache é

menor do que o tempo entre PreLoads, então é necessário fazer o PreLoad de um endereço mais a frente

Page 40: Módulo IV Técnicas de Otimização I Otimizações Gerais usando uma Linguagem Compilada.

Riscos ao Usar o PreLoad

A instrução de PreLoad consome um ciclo de clock, se ele

não melhorar o desempenho, ele poderá piorá-lo

Evite algoritmos que demandem muito custo

computacional para descobrir qual endereço que o

PreLoad usará

Não exagere no uso de PreLoad colocando-o em todo o

código, pois ele também usa um buffer de preenchimento O processador ficará em espera se o buffer de preenchimento

estiver cheio

Page 41: Módulo IV Técnicas de Otimização I Otimizações Gerais usando uma Linguagem Compilada.

Exemplo de PreLoad

void __PreLoad(void *ptr);

void UsePreLoad(int array[], int limit) { int i; for (i = 0; i < limit; i++) { /*Carrega elemento antecipadamente 10 iterações a frente*/ __PreLoad(&(array[i+10]));

/* Código de processamento do array[i] aqui */ } return;}

Inclua o Protótipo

PreLoad chamado para carregar na cache

elementos do array com 10 iterações de antecedência

PreLoad será chamado a cada iteração do laço mesmo que o elemento do array

já esteja na linha da cache.

Page 42: Módulo IV Técnicas de Otimização I Otimizações Gerais usando uma Linguagem Compilada.

Exemplo de PreLoad: Melhoriavoid __PreLoad(void *ptr);

void UsePreLoad(int array[], int limit){ int i; for (i = 0; i < limit; i +=8) { /*Carrega elemento antecipadamente 10 iterações a frente*/ __PreLoad(&(array[i+10])); /* código para array[i]*/ /* código para array[i+1]*/ /* código para array[i+2]*/ /* código para array[i+3]*/ /* código para array[i+4]*/ /* código para array[i+5]*/ /* código para array[i+6]*/ /* código para array[i+7]*/ } return;}

O laço é estendido para poder processar todos os elementos do vetor que estão presentes na

linha de cache carregada da memória

Isso reduz o número de chamadas que são feitas ao

PreLoad com o dado já presente na linha de cache

Page 43: Módulo IV Técnicas de Otimização I Otimizações Gerais usando uma Linguagem Compilada.

Use PreLoad cuidadosamente

O bom senso é necessário para balancear quantos itens estão presentes na linha de cache,

qual o tempo para processar os elementos na linha de cache

determinar o futuro uso de memória que PreLoad precisa carregar

qual o tempo necessário para a carga da cache

Se o PreLoad for chamado a cada iteração do laço carregando linhas da cache não necessárias, junto aos acessos normais do processamento, poderá resultar em esperas devido a falta de entradas vazias no buffer de preenchimento

Page 44: Módulo IV Técnicas de Otimização I Otimizações Gerais usando uma Linguagem Compilada.

Módulo IV

Laboratório