Y a-t-il un inconvénient d'utiliser En particulier, le processeur est susceptible de faire face à une arithmétique entier sur un Je sais que ce sera un processeur / système / compilateur spécifique, mais j'espère une réponse dans l'affaire Général, ou au moins, le cas général pour 32 bits Windows et Solaris, étant les systèmes que je suis travaille actuellement sur. Je suppose également que des problèmes tels que les problèmes de débordement / enveloppement ont déjà été traités. P>
Mise à jour: Visual Studio 6.0 n'a réellement pas Comme note latérale, je n'ai pas passé beaucoup de temps à regarder, mais La première implémentation de char code> pour les petits entiers en C? Y a-t-il des avantages autres que l'avantage d'occupation / mémoire? P>
de chargée de code> mieux ou pire que sur un (
long code> /
court code> court >)
int code>? p>
stdint.h code> comme suggéré par Christoph. Un peu de benchmarking sur Windows (VS 6.0, débogage, 32 bits) avec une poignée de boucles empilées donne
int code> et
long code> comme fournissant des performances similaires, qui est environ deux fois plus que rapide comme
char code>. Exécuter le même test sur Linux avec GCC PEGS
INT CODE> et
LONG code> comme similaire, et à la fois plus rapide que
Char code>, bien que la différence soit moins prononcée. p>
stdint.h code> pour vs 6.0 j'ai trouvé
(via Wikipedia ) Définit uint_fast8_t code> comme
non signé code>, malgré cela semblant être plus lent dans mes tests au moins. Ainsi, la morale de l'histoire, comme Christoph suggéré à juste titre: toujours de référence! P>
6 Réponses :
Eh bien, le premier problème est qu'il n'est pas défini par la standard C si un clair autre que cela, en général Notez que les opérandes plus étroits que char code> est signé ou non signé - la seule plage que vous pouvez contenir de 0 à 127. P>
int code> est censé être le type correspondant à la taille du mot native de l'architecture (mais cela n'est bien sûr appliqué par rien). Cela aurait tendance à être le type avec la meilleure performance arithmétique, mais c'est à peu près tout ce que vous pouvez dire. P>
int code> sont élargis soit à
int code> ou
non signé INT code> lors de l'évaluation d'expression de toute façon. P>
Oui, on m'a dit que A INT a la taille d'un registre de processeur, donc si vous utilisez un caractère, le registre ne sera pas plein mais utilisera toujours le même temps pour faire des opérations basculaires être le registre totalement utilisé ou non.
De plus, INT8_T et UINT8_T seraient de meilleurs types à utiliser que de caractères.
@AIF: Autant que je sache, cela prend même plus i> le temps de faire la conversion haut / bas.
Je suis tombé sur ces 2: << a href = "http://www.evenenthelix.com/realtimantra/basics/optimizingcandcppcode.htm#prefer" rel = "NOWollow NOREFERRER"> EventHelix.com/realtiMemantra/basics/... A> INT sur char et court> et << a href = "http://fr.wikibooks.org/wiki/optimizizing_c%2b%2b/writing_efficient_code/performance_improving_features" rel = "Nofollow NOREFERRER"> EN.WIKIBOOKS.ORG/ wiki / optimizizizing_c% 2b% 2b / écrit_efficient_ code / ... > Mais je ne considère pas non plus autoritaire. Désolé, pas de preuve dure, ressemble plus à l'anecdotique.
Le contenu principal que je verrais, c'est que votre code utilise un type qui signifie une chose pour les valeurs qui signifient autre chose - par exemple, il existe un problème sémantique qui pourrait être un problème de maintenance. Si vous l'avez fait, je vous recommanderais probablement de tapeDefing: de cette façon, a) il est plus clair ce que vous faites, et b) Vous pouvez le changer facilement (par exemple, juste le Un endroit) si vous rencontrez des ennuis. p> Avez-vous un vraiment bonne raison em> ne pas utiliser int code>? p> p>
Votre point sémantique est déjà utilisé dans le seul endroit que j'ai vu cela implémenté. Et non, je n'ai aucune bonne raison, je ne suis que curieux de savoir si cela fait une différence.
Un autre con je peux penser est que (autant que je sache) les processeurs "modernes" font tous leurs mathématiques dans des entiers "pleins", généralement 32 bits. Donc, traiter avec un Utilisation char code> signifie généralement tirer un seul octet hors de la mémoire, remplissant de 0 dans le transfert à un registre, faisant quelque chose avec elle, puis serrant uniquement les bits les moins importants du résultat de la mémoire . Surtout si le
Char code> n'est pas aligné sur une limite pratique, cet accès à la mémoire prend beaucoup plus de travail à accomplir. P>
char code> pour
int code> est vraiment utile lorsque vous avez un lot em> de chiffres (c'est-à-dire un grand tableau) et que vous devez conserver espace. p>
Les caractères nécessitent moins de remplissages de la ligne de cache et sont mieux adaptés au cache.
interne, les processeurs effectuent généralement des arithmétiques sur des mots de la machine. Cela signifie que lorsque lorsque des calculs sur d'autres types sont effectués, bien que le calcul lui-même prenait la même durée, en fonction de l'ensemble d'instructions disponibles, des travaux supplémentaires devraient être effectués pour lire les entrées et pour contraindre les résultats de calcul dans le type cible (par exemple. Signature / remplissage de zéro, changeant / masquage pour éviter les accès à la mémoire non alignée, etc.). P>
C'est pourquoi C définit les types et les opérations telles que c'est - la taille de Raisons valides à utiliser int code> n'est pas mandatée par la norme, permettant aux auteurs du compilateur de le faire correspondre à un mot machine et l'évaluation de l'expression est définie. Pour promouvoir des types entier plus petits à
INT CODE>, réduisant énormément le nombre de points à laquelle les résultats doivent être contraints à un type cible. P>
Char code> pour stocker des valeurs entières sont lorsque l'espace compte vraiment que beaucoup (pas aussi souvent que vous pourriez penser), et lorsque vous décrivez un format / protocole de données externe que vous êtes marshalling données à / vers. Attendez-vous à des utilisations de
Char code> pour inciter une légère perte de performances, en particulier sur le matériel tel que le SPU de cellules où seuls les accès à la mémoire de la taille des mots de la machine sont disponibles, il est donc nécessaire d'accéder à une charcuterie nécessite plusieurs changements et masques. P >
L'arithmétique sur les caractères sera presque certainement réellement effectué en utilisant les mêmes registres que l'arithmétique sur INTS. Par exemple: L'addition compile à ce qui suit avec VC ++: P> où EAX est un registre 32 bits. P > Il n'y a donc pas d'adive d'utilisation des caractères sur InTS lorsqu'il s'agit de performances arithmétiques. P> p>
Oui, mais n'a pas accès à un octet plus lent à cause des problèmes d'alignement? Le fait que l'accès soit une seule ligne d'ASM ne signifie pas qu'il n'y a pas plus de microcode exécuté. Avez-vous une idée de cela?
Coupable comme chargé peut-être trop de simplification sur "remplir avec 0" et "siguant dans un octet". Mais je crois que quelque chose comme ça se passe, à Quelques niveaux i>.
Je n'ai aucune idée de l'accès au bus (que je pense est le vrai problème) des transformateurs modernes, j'ai peur - je répondais à la question de la performance arithmétique.
C99 a ajouté des types d'entiers «les plus rapides» de largeur minimale pour résoudre ce problème. Pour la plage qui vous intéresse, les types seraient Gardez à l'esprit qu'il pourrait ne pas y avoir de gain de performance (l'augmentation de la consommation de mémoire pourrait même réduire les choses); Comme toujours, repère! Ne pas optimiser prématurément ou uniquement sur des hypothèses potentiellement imparfaitantes de ce qui devrait fonctionner. P> int_fast8_t code> et
uint_fast8_t code>, qui peut être trouvé dans
stdint.h p >
Si vous vous souciez de la portabilité (comme je le fais où je partage le code entre cible et PC incorporé), n'utilisez pas de types rapides pour "stocker" quelque chose (membres de la classe, membres de la structure, etc.). Utilisez des types rapides pour itérus, des tableaux d'accès ou une variable de cache locale.
@Mar: L'utilisation de types d'entiers de taille fixe ne suffit pas à garantir que les structures peuvent être sérialisées et désérialisées sur des architectures en raison de l'ordre de rembourrage et d'octet; Comme vous devrez donc sérialiser les membres de la structure de manière séquentielle de toute façon, je ne pense pas qu'il n'y ait rien de mal à utiliser des types rapides pour les variables des membres
@Christoph: Eh bien, c'est non seulement la sérialisation, mais vrai - ma déclaration était trop forte. Cela devrait être plutôt «faire attention à ce sujet» comme une taille accrue peut vous frapper fort dans certains scénarios.
L'analyse comparative est certainement la morale de cette histoire; Je viens de mettre à jour la question avec les résultats d'une benchmarking que j'ai faite. Notamment, la mise en œuvre de STDINT.H que j'ai trouvé pour Visual Studio définit uint_fast8_t comme quelque chose qui est loin du type le plus rapide de mes tests.
Un majeur i> gotcha avec les types STDINT.H est qu'il existe à toutes fins pratiques, aucune garantie de lorsque les mathématiques entre les types signés et non signés produiront un résultat signé ou non signé (car cela est déterminé par la taille de la taille des tailles de les types et la question, plutôt que les types utilisés, et si un savait i> la taille des types en question, on n'aurait pas besoin des types comme uint_fast8_t code> dans le premier lieu). Par exemple, la somme d'un
int32_t code> et a
uint_fast8_t code> peut être un entier 32 bits signé ou non signé, et (sur des machines à 8 ou 16 bits) le produit de Deux
uint8_fast8_t code> valeurs ...
... pourrait être un signé de 16 bits i> int code> qui ne serait pas en mesure de contenir des résultats supérieurs à 32767.