根据维基的说法,中科院所做的事情如下:
function cas(p : pointer to int, old : int, new : int) returns bool {
if *p ≠ old {
return false
}
*p ← new
return true
}嗯,对我来说,如果有几个处理器尝试使用相同的参数执行CAS指令,那么可以同时进行几次写尝试,所以这样做是不安全的。
我哪里错了?
发布于 2016-08-14 09:13:09
原子读-比较-写指令从多个核心在同一时间(在同一高速缓存线)确实相互竞争,但这取决于硬件来分类。原子RMW指令的硬件仲裁在现代CPU中是一个真实的东西,它提供了某种程度的公平性,因此在lock cmpxchg上旋转的一个线程不能完全阻止其他线程执行相同的任务。
(尽管这是一个错误的设计,除非你的重试不需要等待就能成功。为另一个线程修改任何内容,例如,实现fetch_or 或类似的的retry循环可以使用expected的更新值再次尝试。但是,如果等待锁或标志更改,在初始CAS失败后,这样更好将在获取或放松负载上旋转,并且只在可能成功的情况下执行CAS。)
不能保证它们是按什么顺序发生的,这就是为什么您需要仔细设计算法,以便正确性只取决于比较和交换是原子的。( ABA问题是一个常见的陷阱)。
顺便说一句,--整个伪代码块发生在一个原子操作上。将读-比较-写入或读-修改-写作为单个原子操作发生对硬件来说要比仅仅存储要困难得多,而存储MESIF/MOESI处理得很好。
真的吗?我认为这样做是不安全的,因为例如,x86不保证对齐DWORD的写入原子性。
lock cmpxchg使操作具有原子性,而不考虑对齐。对于未对齐的情况,它可能要慢得多,特别是在原子化修改单个缓存行的高速缓存行分割方面。
还请参见x86上的原子性,其中我解释了操作是原子化的含义。
发布于 2016-08-14 09:11:56
如果您阅读wiki,它说CAS“是您发布的代码的以下伪代码的原子版本”。原子意味着代码将在不受其他线程中断的情况下执行。因此,即使有几个线程试图使用相同的参数(如您建议的那样)同时执行此代码,其中只有一个线程将返回true,因为实际上它们不会同时执行,因为原子性要求它们单独运行。
由于您提到"x86不能保证非对齐DWORD的原子性“,所以这里也不是一个问题,因为cas函数的原子属性。
https://stackoverflow.com/questions/38940616
复制相似问题