Question

Je lisais K & R et parlais de la petite section sur les variables de registre. Je me demandais si les gens ici avaient de bons exemples de cela mis en pratique.

De la section 4.7 dans K & amp: R:

  

La déclaration de registre ressemble à
       enregistrer int x;
       enregistrer le caractère c;

Pour être clair, j'espère seulement voir des exemples de code intéressants. Je suis (à peu près sûr de bien comprendre) le sujet, je ne ressens donc pas le besoin de taper une explication verbeuse (à moins que vous ne le vouliez).

Était-ce utile?

La solution

Il n’existe aucun bon exemple d’utilisation du registre lors de l’utilisation de compilateurs modernes (lire: les 15 dernières années), car il n’a pratiquement jamais de résultats positifs et peut en faire de mauvais. Lorsque vous utilisez register, vous dites au compilateur: "Je sais comment optimiser mon code mieux que vous". ce qui n'est presque jamais le cas. Une des trois choses qui peuvent arriver quand vous utilisez register:

  • Le compilateur l'ignore, c'est très probablement. Dans ce cas, le seul inconvénient est que vous ne pouvez pas prendre l'adresse de la variable dans le code.
  • Le compilateur répond à votre demande et par conséquent, le code est plus lent.
  • Le compilateur répond à votre demande et le code s'exécute plus rapidement. Il s'agit du scénario le moins probable.

Même si un compilateur produit un meilleur code lorsque vous utilisez register, il n'y a aucune raison de penser qu'un autre fera de même. Si vous avez du code critique que le compilateur n'optimise pas assez, votre meilleur choix est probablement d'utiliser l'assembleur pour cette partie de toute façon, mais bien sûr, le profilage approprié pour vérifier que le code généré pose vraiment un problème préalable.

Autres conseils

En général, je suis d’accord avec Robert , mais comme toute bonne règle, celle-ci comporte également des exceptions.
Si vous travaillez sur un système profondément intégré, vous savez peut-être mieux que compilateur comment optimiser le code pour votre application spécifique sur votre architecture matérielle spécifique .

Mais dans 99% des cas, l'explication de Roberts convient également pour les mots incorporés.

Je sais que cela remonte à un certain temps, mais voici une implémentation d'une sous-procédure from heapsort dans laquelle l'utilisation de variables de registre rend l'algorithme plus rapide, au moins en utilisant gcc 4.5.2 pour compiler le code

inline  void max_heapify(int *H, int i){
    char OK = FALSE;
    register int l, r, max, hI;
    while(!OK){
        OK = TRUE;
        l = left(i);
        r = right(i);
        max = i;
        if(l <= H[SIZE] && H[l] > H[i]){
            max = l;
        }
        if(r <= H[SIZE] && H[r] > H[max]){
            max = r;
        }
        if(max != i){
            OK = FALSE;
            hI = H[i];
            H[i] = H[max];
            H[max] = hI;
            i = max;
        }
    }
}

J'ai testé l'algortihm avec et sans le mot clé register avant les attributs et je l'ai exécuté pour trier un tableau aléatoire contenant 50 000 000 éléments sur mon bloc-notes, quelques fois pour chaque version.

l'utilisation de registres a fait chuter le temps de chargement de ~ 135s à ~ 125s.

J'ai également testé avec 5 000 000 d'éléments seulement, mais je l'ai exécuté plusieurs fois.

La version sans registre a commencé à 11 secondes, mais chaque exécution a réduit le temps jusqu’à atteindre 9,65 secondes et s’arrête

la version avec le registre a commencé à 10 secondes et a diminué le temps jusqu'à 8,80 secondes.

Je pense que cela a quelque chose à voir avec la mémoire cache. Néanmoins, il semble que les registres rendent l’algorithme plus rapide d’un facteur de constance

Étant donné que ces variables sont très utilisées dans l’algorithme, s’assurer qu’elles figurent dans le registre au lieu de laisser ce travail au compilateur a permis d’obtenir un meilleur résultat dans ce cas. Cependant, le temps n’a guère été amélioré.

J'espère que cela sera utile à quelqu'un, salutations.

Un autre cas courant concerne la mise en œuvre d'interprètes de bas niveau. Garder un état dans les registres, par exemple. pointeur de pile de machine virtuelle, peut réduire considérablement l’accès à la mémoire et accélérer le code.

Voir pour un exemple d'optimisation (5.2 Top of stack stacking).

Tout d’abord, la variable de registre devrait être utilisée pour les variables très utilisées telles que la variable de contrôle de boucle afin d’améliorer les performances en minimisant le temps d’accès. secondaire, vous pouvez utiliser uniquement et enregistrer uniquement le spécificateur de stockage dans cette situation comme, amusement (auto int a, auto int b): erreur              fun (inscrivez-vous int a, inscrivez-vous int b): juste ce serait exécuté              fun (statique int a, statique int b): erreur              fun (extern int a, extern int b): erreur

Bien, c’est une question qui nécessite plusieurs réponses car il existe plusieurs contextes de codage: du point de vue du langage de haut niveau, du niveau moyen au niveau bas (jusqu’à l’assemblage) puisque le langage C peut appeler des routines d’assemblage.

La raison pour laquelle assembly est utilisé à la place de C est principalement liée aux problèmes de performances rencontrés lors du développement. so oui, le mot clé register est nécessaire, mais non, il ne fonctionne pas comme prévu par le développeur dans de nombreux cas.

scroll top