o primeiro eh ter uma ideia da estrategia que sera utilizada pelo codigo e tentar formar uma imagem mental do segmento de codigo que consome mais recursos computacionais. isso vc adquire com o tempo, mas vamos pegar um exemplo geral, para vc perceber que essa estimativa nao passa de um exercicio mental.
por exemplo, desenhar poligonos em um frame buffer consiste em decompor o poligono em triangulos, sendo que cada triangulo eh composto de 3 linhas arbitrariamente diagonais e estas linhas deliminam sucessivas linhas horizontais, que efetivamente preenchem o triangulo. entao em meio a todos estes loops, o loop mais pesado e mais interno eh justamente o loop das linhas horizontais. fazer linhas horizontais consiste em um algoritmo bastante simples em C, algo como:
- Código: Selecionar todos
ptr = line_cache[y]+x;
while(width--)
*ptr++=color;
e cujo loop principal pode ser pensado em asm como:
- Código: Selecionar todos
move y@,a0
move line_cache(a0)@,a1
add x@,a1
move color@,d1
move width@,d2
loop:
move d1,a1@+
dbt d2,loop
nao precisa ser nada preciso, o que vc tem que pensar eh em termos de loop e o que tem dentro do loop. neste caso, tem uma escrita na memoria, ah entao tenho que ver quantos wait-states vai consumir. digamos que eh um processador de 100MHz, mas o bandwidth da memoria nao passa dos 25MHz, entao jah de saida sao 4 wait states ali no move. e quanto isso eh absorvido por pipelines? digamos que eles conseguem sobrepor 1 clock de pre-execucao e 1 clock de pos-execucao, pq envolve um incremento do ponteiro. e tem o loop, digamos que consome 2 clocks. isso vc descobre no datasheet do componente, claro, mas no nosso exemplo, entao, o loop consome 6 clocks. a 100MHz eu consigo entao 16 Mpixel/s. saber quanto cada instrucao consome eh o segundo ponto.
nao rodei a aplicacao, mas jah sei que em cima dos 100 mips teoricos informados pelo fabricante, no fundo eu consigo 16 Mpixel/s. sera que eh suficiente para a aplicacao que eu quero? precisa de mais experiencia. vamos supor que vc tem uma estimativa que vai trabalhar com imagens cuja necessidade eh da ordem de mil triangulos e cada triangulo tem uma media de tamanho de 50 pixels por linha e 50 linhas por triangulo. isso significa preencher 50 mil linhas de 50 pixels, o que totaliza 2.5 milhoes de pixels. assim, essa performance dah somente para trabalhar com 6 frames/s.
sera que nao dah para melhorar? podemos continuar o exercicio mental e procurar alternativas. dominar o hardware eh o terceiro ponto.
vamos pensar do ponto de vista de um canal de DMA dedicado para isso. ele nao eh flexivel, mas no caso de preenchimento de linhas horizontais vc nao precisa de flexibilidade, soh precisa incrementar um ponteiro e transferir um valor fixo de um lugar para outro. daih olha que interessante, muitos processadores possuem sram interna acessivel a zero wait-states, o que permite ler o valor do pixel em um clock. portanto um controlador de DMA poderia fazer o mesmo trabalho consumindo 5 clocks. nao eh uma melhora incrivel, mas aumenta a performance para 20 Mpixel/s e nas mesmas condicoes permite 8 frames/s.
nao esta bom ainda. entao aonde podemos atacar agora? nossa analise esgotou as possibilidades no processador e no controlador de DMA.
podemos tentar entao melhorar a performance da memoria. uma solucao eh diminuir o tempo de acesso, passando, digamos, de 25MHz para 33MHz, assim o numero de wait-states melhora de 4 para 3. assim a transferencia por DMA precisaria de 4 clocks e com isso chegaria a 25Mpixel/s e, portanto, 10 frames/s.
e como melhorar mais sem aumentar o clock da memoria? podemos diminuir a largura do pixel ou deixar a memoria mais larga. se usar pixels de 16 bits em uma memoria de 32 bits, vc dobra a performance chegando a 50Mpixel/s e 20 frames/s. e finalmente, se usar pixels de 8 bits em uma memoria de 32 bits, vc dobra novamente e consegue 100Mpixel/s e 40 frames/s. e assim chegamos no fim da analise com um range de opcoes que varia de 6 a 40 frames/s.
o mundo real eh um pouco mais complexo pq existe um negocio chamado burst, mas vamos deixar isso de lado no momento, pois eh soh um exercicio mental para ver como um processador de "100 mips" eh impactado de forma pesada por memoria externa. eu nao me preocupei em wait-states para instrucoes pq estou pensando em loops e com loops deste tamanho a cache resolve.
entender qual sera o loop critico, entender quantos clocks cada instrucao consome e entender quais as opcoes de hardware para melhorar a performance sao os tres pontos importantes. e claro, o importante disso tudo eh que depois de implementado o projeto vc faca as medicoes, confirme por quanto vc errou e entenda pq vc errou, para poder melhorar as futuras estimativas.
tudo isso para vc se perguntar: estou escolhendo o processador correto para a minha aplicacao? a performance de software sera suficiente? vou precisar de hardware de apoio e terei esse hardware? sera que preciso de um processador maior? ou talvez menor? nao eh questao de economia, mas questao de complexidade e viabilidade: se for algo complexo demais, as chances de nao funcionar sempre aumentam. ao mesmo tempo, se faltar performance, significa que todo o trabalho foi para o lixo e vc tem que recomecar do zero.
rcakto escreveu:Marcelo, então estaria correto em dizer que:
somente comprando e testando todas as capacidades possiveis e analisando o tempo de execução e resultado final em teste da aplicação em que o MCU foi posto que saberei exatamente até aonde o mcu em questão pode chegar e aonde seria recomendado usa-lo?