Выбрать главу

int signed_pwr(register int m, register int e)

{

 register int temp;

 int sign;

 if(m < 0) sign = -1;

 else sign = 1;

 temp = 1;

 for( ; e; e--) temp = temp * m;

 return temp * sign;

}

В этом примере переменные m, е и temp объявлены как регистровые, поскольку все они используются в теле цикла, и потому к ним часто выполняется доступ. Однако переменная sign объявлена без спецификатора register, поскольку она не является частью цикла и используется реже.

Происхождение модификатора register

Модификатор register был впервые определен в языке С. Первоначально он применялся только к переменным типа int и char или к указателям и заставлял хранить переменные этого типа в регистре ЦП, а не в ОЗУ, где хранятся обычные переменные. Это означало, что операции с регистровыми переменными могли выполняться намного быстрее, чем операции с остальными (хранимыми в памяти), поскольку для опроса или модификации их значений не требовался доступ к памяти.

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

Как упоминалось выше, точное количество register-переменных, которые реально будут оптимизированы в любой одной функции, определяется как типом процессора, так и конкретной реализацией C++, которую вы используете. В общем случае можно рассчитывать по крайней мере на две. Однако не стоит беспокоиться о том, что вы могли объявить слишком много register-переменных, поскольку C++ автоматически превратит регистровые переменные в нерегистровые, когда их лимит будет исчерпан. (Это гарантирует переносимость С++-кода в рамках широкого диапазона процессоров.)

Чтобы показать влияние, оказываемое register-переменными на быстродействие программы, в следующем примере измеряется время выполнения двух циклов for, которые отличаются друг от друга только типом управляющих переменных. В программе используется стандартная библиотечная С++-функция clock(), которая возвращает количество импульсов сигнала времени системных часов, подсчитанных с начала выполнения этой программы. Программа должна включать заголовок <ctime>.

/* Эта программа демонстрирует влияние, которое может оказать использование register-переменной на скорость выполнения программы.

*/

#include <iostream>

#include <ctime>

using namespace std;

unsigned int i; //не register-переменная

unsigned int delay;

int main()

{

 register unsigned int j;

 long start, end;

 start = clock();

 for(delay=0; delay<50; delay++)

  for(i=0; i<64000000; i++);

 end = clock();

 cout << "Количество тиков для не register-цикла: ";

 cout << end-start << ' \n';

 start = clock();

 for(delay=0; delay<50; delay++)

  for(j=0; j<64000000; j++);

 end = clock();

 cout << "Количество тиков для register-цикла: ";

 cout << end-start << '\n';

 return 0;

}