Подтвердить что ты не робот

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

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

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

Объявление регистра выглядит так:      register int x;
     register char c;

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

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

Ответ 3

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

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

версия с регистром, начатым в 10 с и опустившим время до 8,80 с.

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

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

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

Ответ 4

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

См. vmgen - генератор эффективных интерпретаторов виртуальных машин для примера оптимизации (5.2 К началу кэширования стека).

Ответ 5

во-первых, переменная регистра должна использоваться для сильно используемых переменных, таких как переменная управления контуром, для повышения производительности за счет минимизации времени доступа. вторичный, вы можете использовать только и только регистрировать спецификатор хранилища в этой ситуации например, fun (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): ошибка