在Intel x86处理器上,是否可以在特定内存位置比较一个值与另一个值,如果比较成功则重置内存而不必担心多线程/处理器问题? 我看到CMPXCHG指令 - 会有用吗? 或者有比较和设置用例的东西?
On an Intel x86 processor, is it possible to compare one value with another at a particular memory location, resetting the memory if the compare succeeded without worrying about multi-thread/processor issues? I see the instruction CMPXCHG - would that work? Or is there something for a compare-and-set use case?
最满意答案
compare-and-set是compare-and-swap的变体,您可以获得内存位置的数据是否与给定值匹配的真/假指示,从而更新内存位置。 compare-and-swap替代方法是从内存中读取内容,您可以自己与给定值进行比较。
http://en.wikipedia.org/wiki/Compare-and-swap
CMPXCHG指令实际上是一个compare-and-set指令。 如果存储器中的值与EAX(隐含寄存器)中给出的值匹配,则设置零标志(EFLAGS.ZF),在这种情况下,源操作数(显式寄存器)中的值存储在存储器中。 要成为compare-and-swap指令,需要从内存读取指令,与EAX 进行比较 , 写入目标存储器并写入源寄存器,即使对于CISC来说 ,这也是不自然的。
您必须使用LOCK前缀来确保CMPXCHG以原子方式执行,也就是说,执行CMPXCHG的线程会在任何其他线程访问它之前读取然后写入内存位置。
你说resetting the memory if the compare succeeded则resetting the memory if the compare succeeded如果你的意思是将内存位置设置为零,那么零是源寄存器中你想要的值。
对于进行compare-and-swap便携方式,请参阅此SO问题中的资源
注意 ,CMPXCHG指令允许目标操作数是寄存器和存储器位置。 测试8个字节时,您将使用CMPXCHG8B指令。 当您在CMPXCHG8B指令上指定LOCK前缀并指定寄存器作为目标时,Pentium处理器中存在错误,您可以在此处阅读更多相关信息。
The CMPXCHG instruction compares the value in an implied register (EAX) with the destination and updates the zero flag (EFLAGS.ZF) to indicate whether the value in the destination matched the value given in EAX in which case the value in the source operand (an explicit register) is stored in the destination. CMPXCHG also updates EAX with the value read from the destination.
Wikipedia describes compare-and-set as a variant of compare-and-swap where you get a true/false indication of whether the data at the memory location matched the given value, and therefore whether the memory location was updated. The compare-and-swap alternative returns the contents read from memory and you can compare with the given value yourself.
http://en.wikipedia.org/wiki/Compare-and-set
... redirects to
http://en.wikipedia.org/wiki/Compare-and-swap
In this sense CMPXCHG is both a compare-and-set and a compare-and-swap.
You must use the LOCK prefix to ensure CMPXCHG is executed atomically, that is, the thread executing CMPXCHG gets to read and then write the memory location before any other thread gets access to it.
You say resetting the memory if the compare succeeded if you mean setting the memory location to zero then zero is the value you want in the source register.
For portable ways of doing a compare-and-swap see resources in this SO question
Note the CMPXCHG instruction allows the destination operand to be a register as well as a memory location. When testing 8 bytes, you would use the CMPXCHG8B instruction. There is a bug in the Pentium processor when you specify a LOCK prefix on the CMPXCHG8B instruction and you specify a register as the destination, you can read more about it here
更多推荐
发布评论