在谈论寄存器分配时,编译文本(例如,Cooper编译工程师)经常提到存储在寄存器中的值必须是“安全的” - 否则它们应该存储在内存中。
什么使得值不安全地保存在寄存器中?
编辑:书中的背景:
“在内存到内存模型中,分配器必须确定哪些值可以安全地保存在寄存器中 - 即哪些值是明确的。”
我能找到的最有用的提及是 “寄存器升级使用指针值的数据流分析来确定基于指针的值何时可以安全地保存在整个循环嵌套中的寄存器中,并重写代码,以便将值保存在新引入的临时变量中。”< / p>
因此,澄清一个问题:为什么指针值存储在寄存器中是不安全的,这是唯一一种在寄存器中无法安全存储值的情况?
答案 0 :(得分:1)
我的理解是,它主要是aliases
的问题。别名是两个或多个名称,在程序中的某个位置引用同一个对象。
别名使得执行一些重要的优化变得非常困难。请考虑以下C示例:
int first, second, *p, *q;
...
first = *p; // store the value from the variable referred to by p in first
*q = 3; // assign to the variable referred to by q
second = *p; // store the value from the variable referred to by p in second
在大多数计算机上,first
的初始分配将要求*p
加载到寄存器中。由于访问内存很昂贵,编译器将希望挂起加载的值,并在分配给second
时重用它。但是,它将无法执行此操作,除非它可以验证p
和q
未引用同一对象(*p
和*q
不是别名) 。
为验证某些名称不是别名而进行的分析称为alias analysis
,并确定何时可以在寄存器中安全地缓存值,计算出#34;无序&#34;或者由并发线程访问。
答案 1 :(得分:0)
稍微不同的代码:
static int x;
int* p;
int first, second;
first = x;
*p = 3;
second = x;
对* p的赋值可能已经改变了x,因此赋值second = x必须再次从内存中读取x,并且不能使用刚存储在第一个中的值,该值可能仍在寄存器中。
答案 2 :(得分:-1)
使用指针变量时,寄存器存储的可用性并不能保证程序的执行速度更快。例如,如果声明的寄存器变量太多,或者没有足够的寄存器可用于存储所有寄存器变量,则某些寄存器中的值必须移动到存储器中的临时存储器,以便清除其他变量的寄存器。而且在这个过程中,将寄存器存储器移动到临时存储器变得不安全。
因此,在寄存器和存储器位置之间来回移动数据可能浪费很多时间。此外,使用指针变量进行变量存储可能会干扰编译器对寄存器的其他使用,例如在表达式求值中存储临时值。最后,如我所提到的,在这种特殊情况下使用寄存器变量实际上可能会导致执行速度变慢。只有在您对所使用的计算机的体系结构和编译器有详细了解时,才应使用寄存器变量。
如果您使用将要放入寄存器的指针变量,最好检查相应的手册。