2010-08-12 6 views
4

D'après ce que je comprends, la définition d'intptr_t varie selon l'architecture - il est garanti d'avoir la capacité de représenter un pointeur qui peut accéder à tout l'espace d'adressage uniforme d'un processus.Micro-optimisations: en utilisant intptr_t pour les types flag/bool

Nginx (populaire serveur web open source) définit un type qui est utilisé comme un flag (booléen) et ceci un typedef à intptr_t. Maintenant, en utilisant l'architecture x86-64 comme exemple - qui a accès à une pléthore d'instructions couvrant des opérandes de toutes tailles - pourquoi définir le drapeau à intptr_t? Sûrement la tradition d'utiliser un type de booléen 32 bits serait tout aussi bien faire l'affaire?

J'ai parcouru le Vs 32 bits. Les booléens de 8 bits argumentent moi-même quand j'étais un nouveau développeur, et la conclusion était que les booléens de 32 bits fonctionnent mieux pour le cas commun en raison des subtilités de la conception de processeur. Pourquoi alors faut-il passer aux booléens 64 bits?

Répondre

2

Les seules personnes qui savent vraiment pourquoi nginx utilise intptr_t pour un type booléen sont les développeurs nginx. Comme vous le dites, les booléens 32 bits fonctionnent souvent mieux que les booléens 8 bits pour le cas courant. Je n'ai pas fait de benchmarking moi-même, mais ça ne me semble pas déraisonnable que pour une certaine situation sur x86-64 un bool 64 bits bat un bool 32-bit. Par exemple, dans la source nginx, j'ai remarqué que la plupart des ngnx_flag_t se produisent dans des structures avec d'autres types typés (u)intptr_t. Un bool 32 bits peut ne pas économiser de l'espace en raison du bourrage d'alignement.

Je trouve le choix pour intptr_t un peu étrange car c'est un type C99 optionnel avec l'intention de convertir vers/depuis void *. Mais autant que je peux voir, il n'est jamais utilisé comme tel. Peut-être que ce type donne la meilleure approximation pour le type «natif» de taille de mot?

0

La booléenne 64bit est une idée terrible pour x86-64. Je suppose que la personne qui l'a écrit pensait à des machines 32 bits avec des pointeurs 32 bits à la fois.

Modern x86 supporte très bien les chargements/magasins non alignés, et permet de déballer un octet pour remplir un registre à la volée. Si x86 est la cible principale, un booléen à 8 bits devrait être préféré, surtout dans les cas où il enregistre des octets, ce qui réduit l'utilisation du cache. Dans le cas rare où le cache n'est pas un problème du tout, 32bit est la taille naturelle, et peut-être enregistrer une instruction dans certains cas où un booléen est ajouté ou multiplié directement avec un int, en permettant au booléen d'être utilisé comme mémoire opérande, au lieu d'être chargé d'un movzx. Pour le cas habituel de test & branche sur un booléen, les processeurs Intel et AMD ont littéralement une différence de performance nulle entre les opérandes 8 bits et 32 ​​bits, que ce soit en mémoire ou dans un registre.

Questions connexes