Вопрос

у меня есть что-то вроде этого

register unsigned int a, b, c;
int n;
for (n = 0; n < 10; ++n){
c = a + b
b = a
a = c
array[n] = c;
}

что он делает, не имеет значения.Код работает быстро, как сейчас, медленнее, если удалить ключевое слово Register.Однако когда я добавляю регистр перед int n, он фактически работает медленнее, чем сейчас, но быстрее, чем если бы регистры не использовались.

Может кто-то объяснить это мне?Спасибо.

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

Решение

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

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

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

Как ты это рассчитал?На практике, register обычно ничего не делает.Это хлам из тех времен, когда технология компиляции была чрезвычайно примитивной и компиляторы не могли сами определить распределение регистров.Предполагалось, что это будет подсказка о необходимости выделения регистра для этой переменной и будет полезна для очень часто используемых переменных.Сейчас большинство компиляторов просто игнорируют это и распределяют регистры по своим алгоритмам.

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

unsigned int array[10];

int n;

#define REG register

int main()
{
    REG unsigned int a, b, c;

    for (n = 0; n < 10; ++n){
        c = a + b;
        b = a;
        a = c;
        array[n] = c;
    }
}

вы получаете (в зависимости от того, определен REG или пуст)

diff http://picasaweb.google.com/lh/photo/v2hBpl6D-soIdBXUOmAeMw?feat=directlink

Слева показан результат использования регистров.

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

Идея использования регистра заключается в том, что ваша переменная используется очень часто.Если с вашей переменной будет произведена какая-либо операция, она все равно будет скопирована в регистр.Таким образом, счетчики (индексные переменные) являются кандидатами на этот модификатор.На примере Диего Торрес Милано от 15 янв. 2010, в 01:57 я бы сделал так:

unsigned int array[10];    

int main()
{
    register int n;
    unsigned int a = 1, b = 2, c;

    for (n = 0; n < 10; ++n){
        c = a + b;
        b = a;
        a = c;
        array[n] = c;
    }
}

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top