2015-02-05 41 views
4

当谈到寄存器分配时,编译文本(例如Cooper编写的Engineering a Compiler)经常提到存储在寄存器中的值需要是“安全的” - 否则它们应该存储在内存中。是什么使一个值不安全的存储在寄存器中?

是什么让一个值不安全的保存在寄存器中?

编辑:从书中语境:

“在内存到内存模式,分配器必须确定哪些值可以安全地在寄存器中,也就是说,它的值是明确保留”

我能找到的信息最多的是 “寄存器升级使用指针值的数据流分析来确定何时可以安全地将整个循环嵌套保存在寄存器中,并重写代码,以便该值保存在新引入的临时变量中。“

为了澄清这个问题:为什么一个指针值不安全地存储在一个寄存器中,并且这是唯一的情况,当一个值无法安全地存储在寄存器中时?

+3

这将有助于提供Cooper在上下文中使用“安全”和/或在本书索引中查找“安全”的引用。 – 2015-02-05 18:45:31

+0

谢谢,我现在编辑了这个问题。 – mijiturka 2015-02-05 18:56:08

+0

我不确定第一个报价,但第二个报价是关于别名分析的 - 当编译器可以证明通过指针加载的值在循环中不会改变时,所以不需要在每次迭代时加载。 – 2015-02-05 18:57:55

回答

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的分配中。但是,它将无法这样做,除非它可以验证pq未引用同一对象(即*p*q不是别名)。

为验证某些名称不是别名而进行的分析称为alias analysis,并确定何时可以将值安全地缓存到寄存器中,这些值是“无序”计算还是由并发线程访问。

0

稍微不同的代码位:

static int x; 
int* p; 
int first, second; 

first = x; 
*p = 3; 
second = x; 

分配给* P可能已经改变X,所以分配第二= x必须再从内存中读取x和不能使用刚存储的值第一,这可能还在注册。

-1

当您使用指针变量时,寄存器存储的可用性不能保证程序的执行速度更快。例如,如果声明了太多的寄存器变量,或者没有足够的寄存器可用于存储所有寄存器变量,则某些寄存器中的值必须移至内存中的临时存储区,以清除其他变量的寄存器。而且在这个过程中,它变成不安全的移动寄存器存储器到临时存储器。

因此,在寄存器和存储器位置之间来回移动数据时可能浪费很多时间。另外,用于变量存储的指针变量的使用可能会干扰编译器对寄存器的其他用途,例如在表达式评估中存储临时值。最后,正如我所提到的,使用寄存器变量实际上可能会导致执行速度变慢。只有在您对所用计算机的体系结构和编译器有详细的了解时,才应该使用注册变量。

如果您使用要放入寄存器的指针变量,最好检查相应的手册。

相关问题