11
votes

Quand utiliser des registres en C?

J'ai quelque chose comme ça xxx

Qu'est-ce que cela fait, peu importe. Le code fonctionne rapidement comme il est maintenant, plus lent si le mot clé de registre est supprimé. Cependant, lorsque j'ajouterai un registre avant que INT N, cela fonctionne réellement plus lentement que maintenant, mais plus rapide que si aucun registre n'est utilisé.

Peut-on m'expliquer cela? Merci.


4 commentaires

Combien de registres à usage général l'architecture cible a-t-elle? Aussi, quel compilateur?


Vous compilez avec des optimisations complètes activées (par exemple, -O3 )? La plupart des optimisations du compilateur, y compris l'allocation de registre, sont désactivées par défaut. Cela rend les timings sur les constructions de débogage (compilées sans une variante sur -o ) sans signification.


Une possibilité, par exemple, c'est que (avec suffisamment d'indicateurs d'optimisation) Votre compilateur préférerait optimiser N-à-delà et plutôt boucle en avançant un pointeur représentant array + n . Peut-être accomplit peut-être l'attention sur votre mot-clé enregistrez , met dans un registre et (par conséquent) ne fait pas l'optimisation qu'il souhaite. mais ce qu'il fait une sorte de matière - (1) il génère des numéros de fibonacci, donc c'est une petite boucle, alors je me méfierais de tout horaire. (2) A et B ne sont pas initialisés, l'optimisateur pourrait donc fondamentalement faire ce qu'il aime avec cela et (par conséquent) produire un code radicalement rapide et brisé.


Oh, et la raison du tableau + n étant plus rapide, s'il est en effet, pourrait être de faire avec des modes d'adressage ou pourrait être parce qu'il utilise un registre moins de cette façon, et si vous forcez l'extra Inscrivez-vous que vous obtenez un déversement de pile dans la boucle. De toute quoi, de toute façon - ce code est assez simple que si vous regardez simplement le démontage pour les deux versions différentes, vous pourrez peut-être voir pourquoi plus lentement est plus lent.


6 Réponses :


13
votes

registre donne au compilateur un indice pour placer la variable dans un registre au lieu de la mémoire / espace de pile. Dans certains cas, il n'y aura pas assez de registres pour chaque variable que vous placez ce mot clé sur le fait de la placer sur trop de variables pouvant forcer certaines des autres de registres à nouveau.

Ce n'est qu'un indice, cependant, et le compilateur n'a pas à le prendre.


3 commentaires

Cela signifie également que vous ne pouvez pas passer la variable par adresse - ou ne devrait pas le faire, car une variable dans un registre n'a aucune adresse.


Passer un registre variable par adresse indique simplement au compilateur de le renverser à empiler. C'est assez légal en C ++ (mais pas ansi c).


Veuillez noter que parfois, il n'ya pas assez de registres disponibles sur puce. Vous venez de Demander Programme à utiliser Inscrivez-vous. Cela peut ne pas l'utiliser.



18
votes

Comment avez-vous choisi ça? En pratique, enregistrer ne fait généralement rien. C'est un morceau de cruft de la technologie du compilateur extrêmement primitif et que les compilateurs ne pouvaient pas comprendre l'allocation d'enregistrement eux-mêmes. Il était censé être un indice pour allouer un registre à cette variable et était utile pour les variables utilisées très fréquemment. De nos jours, la plupart des compilateurs l'ignorent tout simplement et allouent des registres en fonction de leurs propres algorithmes.


7 commentaires

J'ai entendu de nombreux endroits que ce drapeau est ignoré, mais je n'ai jamais rien vu à remonter à ce sujet autre que la rumeur. Avez-vous des sources? Dans mon expérience avec GCC, ce drapeau peut parfois faire une différence (même si j'avoue que cette différence est généralement négative).


@soap Dsimcha a raison, c'est une relique de fois passée. wiki il google it etc - vous trouverez votre preuve.


mais le fait est que j'ai calculé l'heure et je reçois le résultat comme je l'ai dit dans le problème


Comment avez-vous "calculé" l'heure? Pouvez-vous poster l'assemblage généré pour chaque version?


Cela fait une différence dans la GCC lorsque les optimisations sont désactivées (référence: GCC.GNU. Org / Onlinedocs / GCC / Innés-Mise en œuvre.html ).


Bien que l'on se demande pourquoi vous essayez de "optimiser" avec enregistrer lorsque vous compilez sans optimisations.


Il est obsolète en C ++ 0x, oups, 1x: www-949.ibm.com/software/rative/cafe/blogs/cpp-tandard/20 09 / ...



1
votes

Il existe un nombre limité de registres disponibles, alors marquant tout comme registre ne tout mettre pas en compte dans les registres. L'analyse comparative est la seule façon de savoir si cela va vous aider ou non. Un bon compilateur devrait être en mesure de déterminer quelles variables mettaient à des registres à eux-mêmes. Vous devez donc probablement comparer d'autres avant de décider que les mots-clés du registre contribuent.


2 commentaires

"L'analyse comparative est la seule façon de savoir si cela va aider ou non". Eh bien, il dit qu'il a aspiré et qu'il est proposé des résultats pour trois cas différents. Si ses repères sont incorrects, alors lui dire que la référence ne les rendra pas correct ;-)


Il semble étrange qu'il y aurait une différence car un compilateur d'optimisation devrait savoir quelles variables devraient entrer dans des registres, alors je pense qu'il est sage de comparaître à nouveau de s'assurer que cela est bien fait.



-1
votes

Il y a une limite aux registres alloués. Si vous le dépassez, vous venez de vous retrouver avec un code moins efficace.

Ma prise est que si ce que vous faites est si important que vous devez vous décider de ce qui se passe dans un registre et ce que vous ne devez pas l'écrire à l'aide de la langue d'assemblage.

Pour les langues générales, je crois fermement qu'un compilateur est mieux capable de décider de ce qui se passe dans un registre qu'un humain. La preuve étant que si vous n'êtes pas sûr du nombre de variables que vous pouvez mettre dans des registres, votre compilateur sait certainement.


0 commentaires

4
votes

2 commentaires

A quel niveau d'optimisation est-il ignoré?


Cela dépend du code optimisé. Vérifiez l'assembleur généré dans votre cas particulier.



0
votes

L'idée d'utiliser le registre est que votre variable est utilisée extrêmement souvent. S'il y a une opération avec votre variable, elle sera copiée dans un registre de toute façon. Donc, le compteur (les variables d'index) sont des candidats à ce modificateur. Dans l'exemple de Diego Torres Milano em> à partir du 15 janvier '10 à 1:57 Je le ferais de cette façon:

unsigned int array[10];    

int main()
{
    register int n;
    unsigned int a = 1, b = 2, c;

    for (n = 0; n < 10; ++n){
        c = a + b;
        b = a;
        a = c;
        array[n] = c;
    }
}


0 commentaires