2008-11-24 7 views
28

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

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

Декларация регистра выглядит
регистра междунар х;
register char c;

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

ответ

64

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

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

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

+3

«Три вещи могут случиться, а два плохие»? Где я это слышал раньше ... ;-) – 2008-11-25 03:13:38

+0

Помните, что компилятор совершенно свободен игнорировать ваше предложение - в стандарте нет ничего, чтобы сказать, что он должен поместить регистрационную переменную в регистр. – 2008-12-13 22:09:00

+0

также может быть так, что вы пишете компилятор, и вы говорите, что «регистр» для всех локалей в функции сделает функцию без стека. это было бы очень полезно, я думаю. – 2008-12-13 22:51:53

10

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

Но в 99% случаев объяснение Робертса полезно для встроенного слова.

3

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

См. vmgen — a generator of efficient virtual machine interpreters для примера оптимизации (5.2 К началу кэширования стека).

1

Прежде всего, переменная регистра должна использоваться для сильно используемых переменных, таких как переменная управления контуром, для повышения производительности за счет минимизации времени доступа.вторичный, вы можете использовать только и только регистрировать спецификатор хранилища в этой ситуации нравится, забава (auto int a, auto int b): ошибка fun (register int a, register int b): право только это будет выполняться fun (static int a, static int b): ошибка fun (extern int a, extern int b): ошибка

4

Я знаю, что это довольно долгое время, но вот реализация подпроцедуры из 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; 
     } 
    } 
} 

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

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

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

версия без регистра началась в 11s, но каждое исполнение понизило время, пока он не достиг 9,65s и остановился на ней

версии с реестром начался в 10-ых и снизило время до 8,80s.

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

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

Надеюсь, что это поможет кому-то, привет.

Смежные вопросы