Question

Récemment, on m'a mis au défi dans une récente interview accordée à un problème de manipulation de chaînes et a demandé d'optimiser la performance. Je dû utiliser un itérateur pour se déplacer d'avant en arrière entre les caractères TCHAR (avec support UNICODE - 2 octets chacune).

Pas vraiment penser à la longueur du tableau, je fait une erreur curial de ne pas utiliser size_t mais un int pour itérer. Je comprends qu'il est non conforme et non sécurisé.

int i, size = _tcslen(str);    
for(i=0; i<size; i++){
   // code here
}

Mais, la mémoire maximum que nous pouvons allouer est limitée. Et s'il y a une relation entre int et d'enregistrer les formats, il peut être sûr d'utiliser un entier.

Sans .: par exemple des outils de cartographie virtuelle, nous ne pouvons que la carte 2 ^ octets registre taille. Depuis TCHAR est de 2 octets, la moitié de ce nombre. Pour tout système qui a int comme 32 bits, cela ne va pas être un problème, même si vous n'utilisez une version non signée de int. Les gens avec un fond intégré utilisé pour penser int comme 16 bits, mais la taille de la mémoire sera limité sur un tel dispositif. Donc, je me demande s'il y a une décision peaufinage architecturale entre entier et d'enregistrer les formats.

Était-ce utile?

La solution

La norme C ++ ne précise pas la taille d'un int. (Il dit que sizeof(char) == 1 et sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long).

Donc il ne pas Vous pour être une relation d'enregistrer la taille. Une mise en œuvre pleinement conforme ++ C pourrait vous donner 256 octets entiers sur votre PC avec des registres 32 bits. Mais ce serait inefficace.

Alors oui, dans la pratique, la taille du type de données est généralement int égale à la taille des registres à usage général de la CPU, puisque c'est de loin l'option la plus efficace.

Si un était plus grand que short un registre, puis des opérations arithmétiques simples nécessiteraient plus d'une instruction, ce qui serait coûteux. Si elles étaient plus petits qu'un registre, puis le chargement et le stockage des valeurs d'un registre, il faudrait le programme pour masquer les bits non utilisés, pour éviter d'écraser les autres données. (C'est pourquoi le type de données est généralement <=> plus efficace que <=>).

(Certaines langues ont simplement besoin d'un à 32 <=> bits, dans ce cas, il n'y a évidemment pas de relation d'enregistrer la taille --- autre que 32 bits est choisi parce qu'il est une taille de registre commun)

Autres conseils

Aller strictement par la norme, il n'y a aucune garantie quant à la taille / petit un int est, encore moins de rapport à la taille du registre. En outre, certaines architectures ont des tailles différentes des registres (i.e.: tous les registres de la CPU sont de la même taille) et la mémoire n'est pas toujours accessible en utilisant un seul registre (comme DOS avec son segment: offset d'adressage). Avec tout ce que dit, cependant, dans la plupart des cas int est la même taille que les registres « réguliers », car il est censé être le plus couramment utilisé type de base et c'est ce que les processeurs sont optimisés pour fonctionner avec.

AFAIK, il n'y a pas de lien direct entre la taille du registre et la taille int.

Cependant, comme vous le savez pour quelle plate-forme vous compilez l'application, vous pouvez définir votre propre alias de type avec les tailles dont vous avez besoin:

Exemple

#ifdef WIN32 // Types for Win32 target
#define Int16 short
#define Int32 int
// .. etc.
#elif defined // for another target

Ensuite, utilisez les alias déclarés.

Je ne suis pas tout à fait conscient, si je comprends ce correct, car certains problèmes différents (taille de la mémoire, l'allocation, inscrivez-tailles, performance?) Sont mélangés ici.

Ce que je pourrais dire est (juste de prendre le titre), que sur la plupart des processeurs réels pour une vitesse maximale vous devez utiliser des nombres entiers qui correspondent à la taille s'inscrire. La raison est que lorsque vous utilisez des entiers plus petits, vous avez l'avantage d'avoir besoin de moins de mémoire, mais par exemple sur l'architecture x86, une commande supplémentaire pour la conversion est nécessaire. Également sur Intel vous avez le problème, qui accède à unaligned (la plupart du temps sur les limites de taille registre) mémoire donnera une pénalité. Bien sûr, sur les processeurs d'aujourd'hui les choses sont encore plus complexes, car les processeurs sont capables de traiter les commandes en parallèle. Donc, vous finissez par réglage fin pour une architecture.

Donc, la meilleure estimation - sans connaître le architectore -. Speeedwise est, à utiliser le registre de taille ints, aussi longtemps que vous pouvez vous permettre la mémoire

Je n'ai pas une copie de la norme, mais mon ancienne copie de Le langage de programmation C Says (section 2.2) fait référence à int « un entier, ce qui reflète généralement la taille naturelle entiers sur la machine hôte « . Ma copie de Le C ++ langage de programmation dit (section 4.6) « le type est censé <=> être choisi pour être le plus approprié pour maintenir et manipuler des entiers sur un ordinateur donné. »

Vous n'êtes pas la seule personne à dire: « Je vais admettre que cela est techniquement un défaut, mais il est pas vraiment exploitable. "

Il existe différents types de registres avec différentes tailles. Ce qui est important sont les registres d'adresse, pas ceux à usage général. Si la machine est de 64 bits, les registres d'adresse (ou une combinaison d'entre eux) doivent être 64 bits, même si les registres à usage général sont 32 bits. Dans ce cas, le compilateur peut avoir à faire un travail supplémentaire pour calculer réellement les adresses 64 bits en utilisant plusieurs registres à usage général.

Si vous ne pensez pas que les fabricants de matériel font toujours des choix de conception étrange pour leurs registres, vous aviez sans doute jamais faire face à la 8086 d'origine « mode réel " adressage.

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