2 votes

Utilisation de pointeurs profondément imbriqués

Supposons que nous devions utiliser dans une fonction un pointeur profondément imbriqué de manière très extensive :

function (ptr_a_t ptr_a) {
    ...
    a = ptr_a->ptr_b->ptr_c->val;
    b = ptr_a->ptr_b->ptr_c->val;
    ...
}

En supposant que tous les pointeurs sont vérifiés et valides, y a-t-il une dégradation des performances, des problèmes d'atomicité ou d'autres problèmes (sauf la lisibilité) en comparaison avec :

function (ptr_a_t ptr_a) {
    val = ptr_a->ptr_b->ptr_c->val;
    ...
    a = val;
    b = val;
    ...
}

Mise à jour J'ai compilé ce fichier c (écrit uniquement à des fins d'investigation) avec gcc -S :

typedef struct {
  int val;
} c_str_t;

typedef struct {
  c_str_t *p_c;     
} b_str_t;

typedef struct {
  b_str_t *p_b;     
} a_str_t;

void func (a_str_t *p_a) 
{
     int a,b;

     a = p_a->p_b->p_c->val;
     b = p_a->p_b->p_c->val;

     printf("", a,b);
}

Pour gcc -S :

movl    8(%ebp), %eax
movl    (%eax), %eax
movl    (%eax), %eax
movl    (%eax), %eax
movl    %eax, -4(%ebp)
movl    8(%ebp), %eax
movl    (%eax), %eax
movl    (%eax), %eax
movl    (%eax), %eax
movl    %eax, -8(%ebp) 

Pour gcc -S -O1 :

movl    8(%ebp), %eax
movl    (%eax), %eax
movl    (%eax), %eax
movl    (%eax), %eax
movl    %eax, 8(%esp)
movl    %eax, 4(%esp) 

J'observe la même chose en utilisant volatile spécificateur à l'intérieur des structures. Ainsi, les pointeurs imbriqués sont optimisés de manière forcée.

3voto

Karmastan Points 4092

A moins que certains de ces membres intermédiaires de la structure ne soient marqués volatile le compilateur devrait traiter vos deux exemples comme équivalents. Je préférerais votre deuxième exemple de code parce qu'il semble plus propre.

2voto

Remo.D Points 9841

Je suis presque sûr que votre compilateur optimisera les deux au même code que le fait gcc.

Vous pouvez vérifier cela très facilement en générant le code assembleur pour les deux (dans gcc, utilisez le commutateur -S) et comparez-les.

2voto

bta Points 22525

La question de savoir si elles seront traitées de la même manière dépend de la mise en œuvre. Compilez votre code dans les deux sens et examinez la sortie de l'assemblage pour voir comment votre compilateur traite les deux cas.

Sur un système embarqué pour lequel je développe, j'ai ajouté un pointeur "intermédiaire" comme vous l'avez fait et j'ai constaté une accélération appréciable du temps d'exécution de la fonction. Dans mon cas, le compilateur recalculait la chaîne de pointeurs à partir de zéro à chaque fois et ne les optimisait pas. Votre compilateur est peut-être différent, la seule façon de le savoir est d'essayer les deux méthodes et de mesurer le temps d'exécution.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X