Pergunta

usos A maioria dos códigos que eu já li um int para tratamento de erros padrão (valores de retorno de funções e tal). Mas eu estou querendo saber se existe algum benefício a ser tido de usar um uint_8 será um compilador - leia-se: a maioria dos compiladores C na maioria das arquiteturas - instruções de produzir usando o modo de endereço imediata - ou seja, inserir o número inteiro de 1 byte para o instrução? A instrução chave que eu estou pensando é a comparar depois de uma função, utilizando uint_8 como seu tipo de retorno, retorna.

Eu poderia estar pensando sobre as coisas de forma incorreta, como a introdução de um tipo 1 byte apenas provoca problemas de alinhamento - provavelmente há uma razão perfeitamente sã porque compila gostaria de embalar as coisas em 4 bytes e este é possivelmente o motivo todo mundo usa ints -. e desde que esta é uma questão pilha relacionada ao invés da pilha não há nenhuma sobrecarga verdadeiro

Fazer a coisa certa é o que eu estou pensando. Mas vamos dizer que dizer para o bem do argumento este é um microprocessador barato popular para um relógio inteligente e que está configurado com 1k de memória, mas tem diferentes modos de endereçamento em seu conjunto de instruções: D

Outra questão a se especializar um pouco a discussão (x86) seria: é a literal em:

uint_32 x=func(); x==1;

e

uint_8 x=func(); x==1;

o mesmo tipo? ou será o compilador gera um literal de 8 bytes no segundo caso. Se assim for, pode usá-lo para gerar uma instrução de comparar qual tem o literal como um valor imediato eo int retornado como uma referência de registo. Veja CMP tipos de instruções. .

Outra Refference para o conjunto de instruções x86.

Foi útil?

Solução

Aqui está o que um compilador particular irá fazer para o seguinte código:

extern int foo(void) ;
void bar(void)
{
        if(foo() == 31) { //error code 31
                do_something();
        } else {
                do_somehing_else();
        }
}

   0:   55                      push   %ebp
   1:   89 e5                   mov    %esp,%ebp
   3:   83 ec 08                sub    $0x8,%esp
   6:   e8 fc ff ff ff          call   7 <bar+0x7>
   b:   83 f8 1f                cmp    $0x1f,%eax
   e:   74 08                   je     18 <bar+0x18>
  10:   c9                      leave
  11:   e9 fc ff ff ff          jmp    12 <bar+0x12>
  16:   89 f6                   mov    %esi,%esi
  18:   c9                      leave
  19:   e9 fc ff ff ff          jmp    1a <bar+0x1a>

a instrução 3 bytes para o CMP. se foo () retorna um char, obtemos b: 3c 1F cmp $ 0x1f,% al

Se você está procurando a eficiência embora. Não assuma comparando coisas em% a1 é mais rápido do que comparando com% eax

Outras dicas

Pode haver pequenas diferenças de velocidade entre os diferentes tipos integrais sobre uma arquitetura particular. Mas você não pode contar com ele, isso pode mudar se você se mover para um hardware diferente, e pode até ficar mais lento se você atualizar para hardware mais recente.

E se você falar sobre x86 no exemplo você está dando, você faz uma falsa premissa: Um necessidades imediatas para ser do tipo uint8_t.

Na verdade imediatos 8 bits incorporados na instrução são do tipo int8_t e pode ser usado com bytes, palavras, e dwords qwords, em notação C:. char, short, int e long long

Assim, nesta arquitetura não haveria nenhum benefício em tudo, nem o tamanho do código, nem a velocidade de execução.

Você deve usar tipos int int ou não assinados para seus cálculos. Utilizando tipos menores apenas para compostos (structs / matrizes). A razão para isso é que int é normalmente definido como sendo o tipo integral "natural mais" para o processador, todo outro tipo de derivado pode necessitar de processamento a funcionar correctamente. Tivemos no nosso projeto compilado com gcc no Solaris para SPARC o caso que acessa a 8 e 16 bit variável acrescentou uma instrução para o código. Ao carregar um tipo menor de memória que ele tinha que ter certeza da parte superior do registo foi correctamente definido (extensão de sinal para o tipo assinado ou 0 para não assinado). Este feito o código de mais tempo e o aumento da pressão nos registos, o que deterioraram as outras optimizações.

Eu tenho um exemplo concreto:

Eu declarei duas variáveis ??de uma struct como uint8_t e tenho esse código em Sparc Asm:

    if(p->BQ > p->AQ)

foi traduzido em

ldub    [%l1+165], %o5  ! <variable>.BQ,
ldub    [%l1+166], %g5  ! <variable>.AQ,
and     %o5, 0xff, %g4  ! <variable>.BQ, <variable>.BQ
and     %g5, 0xff, %l0  ! <variable>.AQ, <variable>.AQ
cmp     %g4, %l0    ! <variable>.BQ, <variable>.AQ
bleu,a,pt %icc, .LL586  !

E aqui o que eu tenho quando eu declarou que as duas variáveis ??como uint_t

lduw    [%l1+168], %g1  ! <variable>.BQ,
lduw    [%l1+172], %g4  ! <variable>.AQ,
cmp     %g1, %g4    ! <variable>.BQ, <variable>.AQ
bleu,a,pt %icc, .LL587  !

Duas operações aritméticas menos e 2 registros mais para outras coisas

Processadores normalmente gosta de trabalhar com seus tamanhos registo naturais, que em C é 'int'.

Embora haja exceções, você está pensando muito em um problema que não existe.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top