这种时候就要看规范了。
规范没规定register一定要用寄存器。
register - automatic duration and no linkage; address of this variable cannot be taken
2) The register specifier is only allowed for objects declared at block scope, including function parameter lists. It indicates automatic storage duration and no linkage (which is the default for these kinds of declarations), but additionally hints the optimizer to store the value of this variable in a CPU register if possible. Regardless of whether this optimization takes place or not, variables declared register cannot be used as arguments to the address-of operator, cannot use alignas (since C11), and register arrays are not convertible to pointers.
看不懂英文的话,中文翻译:存储类指定符 - cppreference.com
register - 自动存储期与无链接;不能取这种对象的地址
2) register 指定符只对声明于块作用域的对象允许,包括函数参数列表。它指示自动存储期与无链接(即这种声明的默认属性),但另外提示优化器,若可能则将此对象的值存储于 CPU 寄存器中。无论此优化是否发生,声明为 register 的对象不能用作取址运算符的参数,不能用 _Alignas (C11 起),而且 register 数组不能转换为指针。
规范上只是规定可能,而不是必须。
另外,你这个计时粒度太粗了,而且要测性能,还要独占CPU,甚至还需要关闭调试信息才行。
下面是一个VC2017的代码。
使用内联汇编和高精度计数器计时。
#include <stdio.h> #include <Windows.h> #define TIME 1000000000 int m, n = TIME; int main() { LARGE_INTEGER freq, start, end; int x, y = TIME; if (QueryPerformanceFrequency(&freq) == FALSE) { printf("Can not get performance freq
"); return -1; } printf("freq = %lld
", freq.QuadPart); if (QueryPerformanceCounter(&start) == FALSE) { printf("Fail to get counter
"); return -1; } for (m = 0; m < n; m++); if (QueryPerformanceCounter(&end) == FALSE) { printf("Fail to get counter
"); return -1; } printf("Counter = %lld Time = %lld ms
", end.QuadPart - start.QuadPart, (end.QuadPart - start.QuadPart) * 1000 / freq.QuadPart); if (QueryPerformanceCounter(&start) == FALSE) { printf("Fail to get counter
"); return -1; } for (x = 0; x < y; x++); if (QueryPerformanceCounter(&end) == FALSE) { printf("Fail to get counter
"); return -1; } printf("Counter = %lld Time = %lld ms
", end.QuadPart - start.QuadPart, (end.QuadPart - start.QuadPart) * 1000 / freq.QuadPart); if (QueryPerformanceCounter(&start) == FALSE) { printf("Fail to get counter
"); return -1; } __asm { push ecx; push ebx; mov ecx, 0; mov ebx, TIME; loop1: inc ecx; cmp ecx, ebx; jne loop1; pop ebx; pop ecx; } if (QueryPerformanceCounter(&end) == FALSE) { printf("Fail to get counter
"); return -1; } printf("Counter = %lld Time = %lld ms
", end.QuadPart - start.QuadPart, (end.QuadPart - start.QuadPart) * 1000 / freq.QuadPart); return 0; }
Windows上运行结果:
freq = 3023438 Counter = 6030087 Time = 1994 ms Counter = 6040404 Time = 1997 ms Counter = 747601 Time = 247 ms
寄存器的速度还是快的很明显。
Linux下GCC代码(使用rdtsc获得高精度计时):
#include <stdio.h> #define TIME 1000000000 #define STR(x) #x #define INT2STR(x) STR(x) int m, n = TIME; long long GetTSC() { long long tsc; __asm__ __volatile__ ("rdtsc" : "=A" (tsc)); return tsc; } int main() { long long start, end; int x, y = TIME; start = GetTSC(); for (m = 0; m < n; m++); end = GetTSC(); printf("Counter = %lld Time = %lld ms
", end - start, (end - start) / 1000000); start = GetTSC(); for (x = 0; x < y; x++); end = GetTSC(); printf("Counter = %lld Time = %lld ms
", end - start, (end - start) / 1000000); start = GetTSC(); __asm__("pushl %ecx
" "pushl %ebx
" "movl $0, %ecx
" "movl $" INT2STR(TIME) ", %ebx
" "loop1: incl %ecx
" "cmp %ecx, %ebx
" "jne loop1
" "popl %ebx
" "popl %ecx
"); end = GetTSC(); printf("Counter = %lld Time = %lld ms
", end - start, (end - start) / 1000000); return 0; }
运行结果
Counter = 5690200100 Time = 5690 ms Counter = 5730137064 Time = 5730 ms Counter = 628730072 Time = 628 ms