AtomicCmpExchange在所有平台上都可靠吗?

lok*_*oki 10 delphi

我找不到AtomicCmpExchange(似乎隐藏)的实现,所以我不知道它的作用.

AtomicCmpExchange在所有平台上可靠吗?它是如何在内部实施的?它是否使用类似临界区的东西?

我有这种情况:

MainThread:

Target := 1;
Run Code Online (Sandbox Code Playgroud)

线程1:

x := AtomicCmpExchange(Target, 0, 0);
Run Code Online (Sandbox Code Playgroud)

线程2:

Target := 2;
Run Code Online (Sandbox Code Playgroud)

Thread3:

Target := 3;
Run Code Online (Sandbox Code Playgroud)

x永远是一个整数1,2或3,或可能是别的东西吗?我的意思是,即使AtomicCmpExchange(Target, 0, 0)未能交换该值,它是否返回一个"有效"整数(我的意思是,不是半读取整数,例如,如果另一个线程已经开始写入该值的一半)?

我想避免使用临界区,我需要最大速度.

All*_*uer 16

AtomicCmpExchange是所谓的内在例程标准函数.它本质上是编译器所知的,可能有也可能没有可见的实现.例如,Writeln是标准函数,但您不会找到它的单个实现.编译器将其分解为对System.pas中的低级函数的多次调用.一些标准功能,如Inc()Dec()不具备任何System.pas执行.编译器将生成相当于简单INCDEC指令的机器指令.

喜欢Inc()或者Dec(),AtomicCmpExchange()使用给定平台所需的任何代码来实现.它将生成内联指令.对于x86/x64,它将生成一条CMPXCHG指令(以及将变量/值放入寄存器所需的任何设置).对于ARM,它将围绕LDREXSTREX指令生成更多指令.

所以直接回答你的问题是,即使调入汇编代码,你不能得到更有效的利用相比,与其他如沿着标准功能AtomicIncrement,AtomicDecrement以及AtomicExchange.

  • 值得注意的是,必须对齐变量 (3认同)
  • 是的,它将始终返回有效的整数。如果目标的值与比较符匹配,则将交换该值,并且返回值是目标的先前值。如果目标不匹配,则返回该值。所有这些都是原子完成的,这意味着它可以完成,而无需担心中间状态将其弄乱。 (2认同)