百科问答小站 logo
百科问答小站 font logo



都说寄存器比内存快,但是为什么有些时候运行显示的是寄存器更慢? 第1页

  

user avatar   bei-ji-85 网友的相关建议: 
      

这种时候就要看规范了。

规范没规定register一定要用寄存器。

规范:Storage-class specifiers

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     




  

相关话题

  为什么 lea 会被用来计算? 
  if(x>y)和if(x-y>0)有没有区别(x,y都是int)? 
  为什么一个36字节的文本文档占用空间0字节? 
  汇编语言转换成机器语言,具体在机器这个层面是如何实现的? 
  向下扩展的段,为什么偏移量是从limit+1 ~ 0xFFFF? 
  都说寄存器比内存快,但是为什么有些时候运行显示的是寄存器更慢? 
  现在主存的速度已经超过CPU的速度,那么CPU片内的cache是否可以取消? 
  计算机科班生学计算机组成原理的意义何在呢? 
  高级语言如何转汇编语言的问题? 
  采用32位cpu的系统,如果内存采用字编址方式能否支持更大的内存了? 

前一个讨论
你认为自己颜值巅峰是哪一张照片?
下一个讨论
是否有可能以USB Type-C物理接口替代SATA物理接口?





© 2024-11-09 - tinynew.org. All Rights Reserved.
© 2024-11-09 - tinynew.org. 保留所有权利