Power PC提供了几个用于互斥操作的指令,采用这些指令可以完成多CPU环境下的同步操作。最典型的是下列两个指令:
(1)lwarx(Load word and reserve index)指令。该指令的作用是读取内存中的一个特定字(在Power PC中,字的长度是32比特的,而在IA32中,字的长度定义为16比特)到一个特定的寄存器,然后设置一个Reserve位,并启动内存窥探机制,对上述内存位置进行监控。一旦该内存位置被修改(可能是其他的处理器),则清除Reserve比特,否则一直保持Reserve比特。该指令的格式为:lwarx rD,rA,rB(其中,rA和rB寄存器给出了Effective地址,该指令把Effective地址位置的字读入rD寄存器,该Effective地址也是内存窥探机制作用的目标地址)。
(2)stwcx(Store word conditional indexed)指令。该指令与上述lwarx指令对应,用来协同完成同步机制。该指令的作用是判断Reserve比特是否为1,若为1,则设置指定地址位置的字为指定字(由该指令的操作数寄存器指定内存位置和指定字,一般情况下,指定的内存位置与lwarx指令指定的有效地址相同),清除Reserve标志,并设置一个成功标志(CR0寄存器的特定比特);若Reserve标志为0,则该指令不做任何其他操作,仅仅设置一个失败标志(CR0寄存器的特定比特)。该指令的格式与lwarx类似:stwcx rS,rA,rB,其中,rA和rB两个通用寄存器指定Effective地址,rS寄存器指定要存储的值。
上述简单的描述仅仅是这两个指令的基本用途,这两个指令还有一些其他的用途,在此不再详述。
许多较复杂的原子操作和同步操作都可以采用上述两条指令实现。比如下列代码实现了一个简单的Test-and-set例程:
(www.xing528.com)
上述代码中,假设r3寄存器存放了要测试的内存位置(Effective地址),lwarx执行后,把该位置的一个字读入r5寄存器,并设置Reserve比特。第二条指令(cmpwi),用于比较r5寄存器的值是否为0(即原内存位置的字是否为0),若不为0,则跳转到continue标号处执行,若为0,则继续执行。这时候,stwcx指令根据Reserve比特的值来确定是否把r4寄存器的值(非0)存放到上述内存位置。若成功(Reserve比特为1,成功地把r4寄存器的值,存放到r3指定的有效地址处),则跳出循环,继续执行,否则跳转到loop标号处,重新执行上述操作。
上述操作是一个原子操作,考虑在多CPU的环境下,一种访问冲突的情况:假设有两个CPU(CPU1和CPU2)试图同时对同一个位置进行Test and set操作,则表7-2所示的情况可能发生。
表7-2 一个产生访问冲突的指令序列(双CPU)
在上述序列下,CPU1和CPU2会把r3指定的内存位置处的数字,读入r5寄存器,由于这时该位置还没有被修改,所以cmpwi指令的执行结果都会比较成功,从而导致stwcx指令的执行。这时候,CPU2可以成功执行该指令,因为在CPU2执行前,该位置尚未被修改;但CPU1却执行失败,因为在CPU1执行stwcx前,CPU2已经修改了该位置(CPU1通过内存窥探机制得知),从而导致Reserve标志被清除。这样目标为同一位置的test and set操作,只有一个CPU设置成功,其他CPU都没有设置成功,从而实现了共享资源的同步和保护。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。