Использование глубоко вложенных указателей - PullRequest
2 голосов
/ 26 июня 2010

Предположим, мы должны очень широко использовать в некоторых функциях глубоко вложенный указатель:

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

При условии, что все указатели проверены и допустимы, есть ли снижение производительности, проблемы с атомарностью или другие предупреждения (кроме читабельности)сравнение с:

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

Обновление Я скомпилировал этот файл c (написанный только для исследовательских целей) с помощью 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);
}

Для 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) 

Для gcc -S -O1:

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

То же самое я наблюдаю, используя volatile specifierвнутри структур.Таким образом, вложенные указатели принудительно оптимизируются.

Ответы [ 3 ]

3 голосов
/ 26 июня 2010

Если некоторые из этих промежуточных членов структуры не помечены volatile , компилятор должен рассматривать ваши два примера как эквивалентные.Я бы предпочел ваш второй пример кода только потому, что он выглядит чище.

2 голосов
/ 26 июня 2010

Будут ли они рассматриваться как одинаковые, зависит от реализации. Скомпилируйте ваш код в обоих направлениях и проверьте вывод сборки, чтобы увидеть, как ваш компилятор обрабатывает оба случая.

На встраиваемой системе, для которой я разрабатываю, я добавил «промежуточный» указатель, как вы, и увидел заметное ускорение времени выполнения функции. В моем случае компилятор каждый раз пересчитывал цепочку указателей с нуля и не оптимизировал их. Ваш компилятор может отличаться, единственный реальный способ определить это - попробовать оба варианта и измерить время выполнения.

2 голосов
/ 26 июня 2010

Я почти уверен, что ваш компилятор оптимизирует оба кода под тот же код, что и gcc.

Вы можете легко проверить это, сгенерировав код ассемблера для обоих (в gcc используйте ключ -S) и сравнив их.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...