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 был впервые определен в языке С. Первоначально он применялся только к переменным типа 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;
}