Question

La plupart du code que j'ai jamais lu utilise un int pour la gestion des erreurs standard (valeurs de retour des fonctions et autres). Mais je me demande s'il y a un bénéfice à tirer d'utiliser un uint_8 un compilateur sera - lire: la plupart des compilateurs C sur la plupart des architectures - produire des instructions en utilisant le mode d'adresse immédiate - à savoir, intégrer l'entier 1 octet dans la instruction ? L'instruction clé Je pense à la comparaison est après une fonction, en utilisant uint_8 comme type de retour, les retours.

Je pourrais penser à des choses de manière incorrecte, comme l'introduction d'un 1 type octet causes justes des problèmes d'alignement - il y a probablement une raison parfaitement sain d'esprit pourquoi compile comme pour emballer les choses en 4 octets, ce qui est peut-être la raison tout le monde utilise juste ints -. et comme cela est pile problème lié plutôt que le tas il n'y a pas de frais généraux réel

Faire la bonne chose est ce que je pense. Mais disons que dire pour le bien de l'argument que c'est un microprocesseur pas cher populaire pour une montre intelligente et qu'il est configuré avec 1k de la mémoire, mais ne dispose différents modes d'adressage dans son jeu d'instructions: D

Une autre question se spécialiser un peu la discussion (x86) serait la suivante: est le littéral:

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

et

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

le même type? ou bien le compilateur générer un octet de 8 littéral dans le second cas. Dans ce cas, il peut l'utiliser pour générer une instruction de comparaison qui a le sens littéral comme une valeur immédiate et l'int retourné comme une référence de registre. Voir les types d'instruction CMP. .

Une autre Refference pour le jeu d'instructions x86.

Était-ce utile?

La solution

Voici ce qu'un compilateur particulier va faire pour le code suivant:

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>

une instruction de 3 octets pour la CMP. si retourne char foo (), nous obtenons  b: 3c 1f cmp $ 0x1f,% al

Si vous êtes à la recherche d'efficacité bien. Ne présumez pas comparait des choses en% a1 est plus rapide que la comparaison avec% eax

Autres conseils

Il peut y avoir de très petites différences de vitesse entre les différents types intégrés sur une architecture particulière. Mais vous ne pouvez pas compter sur elle, il peut changer si vous vous déplacez vers un matériel différent, et si vous mettez à niveau vers du matériel plus récent peut même fonctionner plus lentement.

Et si vous parlez x86 dans l'exemple que vous donnez, vous faites une fausse hypothèse: Un besoin immédiat d'être de type uint8_t.

En fait immediates 8 bits incorporés dans les instructions sont de type int8_t et peut être utilisé avec des octets, des mots, doubles mots et qwords, en notation C: char, short, int et long long

.

sur cette architecture il n'y aurait aucun avantage, ni la taille du code, ni la vitesse d'exécution.

Vous devez utiliser les types int int ou non signés pour vos calculs. Utilisation des types plus petits que pour les composés (structs / tableaux). La raison en est que int est normalement défini comme le type intégral « plus naturel » pour le processeur, tout autre type dérivé peut nécessiter un traitement pour fonctionner correctement. Nous avions dans notre projet compilé avec gcc sur Solaris pour SPARC le cas qui accède à 8 et 16 variable bit ajouté une instruction au code. Lors du chargement d'un type plus petit de la mémoire, il a dû assurer que la partie supérieure du registre a été réglé correctement (extension de signe pour le type signé ou 0 pour non signé). Cela rend le code plus et une pression accrue sur les registres qui se sont dégradés les autres OPTIMISATIONS.

J'ai un exemple concret:

Je déclarai deux variables d'une struct uint8_t et obtenu ce code dans Sparc Asm:

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

a été traduit en

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  !

Et voici ce que je suis quand je déclarai les deux variables comme 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  !

Deux opérations arithmétiques moins et 2 registres plus pour d'autres choses

Processeurs aime généralement travailler avec leurs tailles de registre naturel, qui est C « int ».

Bien qu'il existe des exceptions, vous pensez trop sur un problème qui n'existe pas.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top