Какой хороший пример использования регистровых переменных в C?

StackOverflow https://stackoverflow.com/questions/314994

Вопрос

Я читаю K & R и наткнулся на небольшой раздел о регистровых переменных, и мне стало интересно, есть ли у людей здесь какие-нибудь хорошие примеры применения этого на практике.

Из раздела 4.7 в K & R:

Объявление регистра выглядит следующим образом
зарегистрировать int x;
зарегистрировать символ c;

Чтобы было понятно, я просто надеюсь увидеть несколько интересных примеров кода.Я (почти уверен, что я) разбираюсь в предмете, поэтому не считаю нужным вводить подробное объяснение (если вы этого не хотите).

Это было полезно?

Решение

Нет хорошего примера использования регистра при использовании современных компиляторов (читать:последние 15 с лишним лет), потому что это почти никогда не приносит никакой пользы и может принести немного вреда.Когда вы используете register, вы говорите компилятору: "Я знаю, как оптимизировать свой код лучше, чем вы", чего почти никогда не бывает.При использовании register может произойти одна из трех вещей:

  • Компилятор игнорирует его, это наиболее вероятно.В этом случае единственный вред заключается в том, что вы не можете использовать адрес переменной в коде.
  • Компилятор выполняет ваш запрос, и в результате код выполняется медленнее.
  • Компилятор выполняет ваш запрос, и код выполняется быстрее, это наименее вероятный сценарий.

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

Другие советы

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

Но в 99% случаев объяснение Робертса также хорошо для встроенного слова.

Я знаю, что это довольно давно, но здесь есть реализация подпроцедуры из heapsort, в которой использование переменных регистров ускоряет алгоритм, по крайней мере, с помощью gcc 4.5.2 для компиляции кода

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;
        }
    }
}

Я протестировал алгоритм с и без ключевого слова register перед атрибутами и выполнил его, чтобы отсортировать случайный массив с 50 000 000 элементов в моей записной книжке, несколько раз для каждой версии.

использование регистров сократило время сортировки с ~ 135 до ~ 125 с.

Я также протестировал только 5 000 000 элементов, но выполнил его несколько раз.

Версия без регистра начиналась в 11 с, но каждое выполнение уменьшало время до 9,65 с и останавливалось на этом

версия с регистром началась в 10 секунд и снизила время до 8,80 секунд.

Я думаю, что это как-то связано с кеш-памятью. Тем не менее, кажется, что регистры ускоряют алгоритм благодаря постоянному коэффициенту

Поскольку эти переменные довольно часто используются в алгоритме, то, гарантируя, что они находятся в регистре, вместо того, чтобы оставлять эту работу компилятору, в этом случае был достигнут лучший результат. Тем не менее, это не сильно улучшило время.

Надеюсь, что это будет полезно для кого-то, привет.

Ну, это вопрос, требующий нескольких ответов, потому что существует несколько контекстов кодирования: с точки зрения языка высокого уровня, среднего уровня и низкого уровня (вплоть до сборки), поскольку язык C может вызывать процедуры сборки.

Причиной использования сборки вместо C является просто причина в проблемах производительности, возникающих во время разработки, так что да, существует необходимость в ключевом слове register, но во многих случаях оно не работает так, как задумывалось разработчиком

scroll top