Uma otimização interessante…

Eis um caso onde você pode conseguir um código um cadinho mais rápido trocando uma divisão (ou uma multiplicação) por operações aritméticas mais simples. No T50 eu tinha uma rotina assim:

...
  /* Obtém a netmask com base num valor aleatório. */
  return shift(8 + (rand() % 23));
...

A rotina obtém um valor da função rand() e calcula o resto da divisão para o caso do valor ser maior que 22. Isso quer dizer que a rotina fará um shift, de um certo valor entre 8 e 30 bits (22 + 8). Olha só a engronha que é gerada pelo compilador:

...
  sub  rsp,8
  call rand
  mov  edx,-1307163959
  add  rsp,8
  mov  edi,eax
  imul edx
  mov  eax,edi
  sar  eax,31
  add  edx,edi
  sar  edx,4
  sub  edx,eax
  mov  eax,23
  imul edx,eax
  sub  edi,edx
  add  edi,8
  jmp  shift
...

Agora, dê uma olhada neste código:

...
  /* Obtem rand() de 0 até 31. */
  unsigned int r = rand() & 0x1f;

  /* Obtém o resto, mas usando aritmética fundamental! */
  if (r > 22)
    r = -(23 - r);

  return shift(8 + r);
...

E, voilà! O código resultante é bem menor e mais rápido (não tem nenhuma multiplicação ou divisão!):

...
  sub  rsp, 8
  call rand
  and  eax, 0x1f
  lea  edx, [rax-23]
  cmp  eax, 23
  cmovnb eax, edx
  add  rsp, 8
  lea  edi, [rax+8]
  jmp  shift
...

O ponto que pode causar estranheza é a inversão de sinal depois da subtração. Estamos trabalhando com valores sem sinal, certo? Acontece que o operador unário ‘-‘ não faz o que você imagina: Ele inverte o sinal do seu operando usando complemento 2. E isso pode ser feito com qualquer inteiro!

O mesmo efeito pode ser obtido usando a chamada abs() de stdlib.h, ao invés do operador unário de mudança de sinal…

Fica a dica…

Anúncios

Deixe um comentário

Faça o login usando um destes métodos para comentar:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s