![](/img/trans.png)
[英]Haskell: Attempt at parallel `atomicModifyIORef` implementation
[英]Haskell: How does 'atomicModifyIORef' work?
有人可以解释atomicModifyIORef
是如何工作的吗? 特别是:
(1) 它是等待锁定,还是乐观地尝试并在存在争用时重试(如TVar
)。
(2) 为什么 atomicModifyIORef 的签名与atomicModifyIORef
的签名modifyIORef
? 特别是,这个额外的变量b
是什么?
编辑:我想我已经找到了 (2) 的答案,因为b
是要提取的值(如果不需要,它可以为空)。 在单线程程序中,知道该值是微不足道的,但在多线程程序中,人们可能想知道在应用 function 时的先前值是什么。 我认为这就是为什么modifyIORef
没有这个额外的返回值(因为带有这个返回值的modifyIORef
的用法可能无论如何都应该使用atomicModifyIORef
。不过我仍然对(1)的答案感兴趣。
它是等待锁定,还是乐观地尝试并在存在争用时重试(如 TVar)。
atomicModifyIORef 在您所在的底层硬件架构上使用锁定指令,以原子方式将指针交换到分配的 Haskell object。
在 x86 上,它使用 cas 指令,通过atomicModifyMutVar#
作为语言的原语公开,它在 Cmm 中作为运行时服务实现为:
stg_atomicModifyMutVarzh
{
...
retry:
x = StgMutVar_var(mv);
StgThunk_payload(z,1) = x;
#ifdef THREADED_RTS
(h) = foreign "C" cas(mv + SIZEOF_StgHeader + OFFSET_StgMutVar_var, x, y) [];
if (h != x) { goto retry; }
#else
StgMutVar_var(mv) = y;
#endif
...
}
也就是说,它将尝试进行交换,否则重试。
cas 作为原语的实现展示了我们如何深入研究金属:
/*
* Compare-and-swap. Atomically does this:
*/
EXTERN_INLINE StgWord cas(StgVolatilePtr p, StgWord o, StgWord n);
/*
* CMPXCHG - the single-word atomic compare-and-exchange instruction. Used
* in the STM implementation.
*/
EXTERN_INLINE StgWord
cas(StgVolatilePtr p, StgWord o, StgWord n)
{
#if i386_HOST_ARCH || x86_64_HOST_ARCH
__asm__ __volatile__ (
"lock\ncmpxchg %3,%1"
:"=a"(o), "=m" (*(volatile unsigned int *)p)
:"0" (o), "r" (n));
return o;
#elif arm_HOST_ARCH && defined(arm_HOST_ARCH_PRE_ARMv6)
StgWord r;
arm_atomic_spin_lock();
r = *p;
if (r == o) { *p = n; }
arm_atomic_spin_unlock();
return r;
#elif !defined(WITHSMP)
StgWord result;
result = *p;
if (result == o) {
*p = n;
}
return result;
所以你可以看到它能够在 Intel 中使用原子指令,在其他架构上将使用不同的机制。 运行时将重试。
atomicModifyIORef
采用r:: IORef a
和 function f:: a -> (a, b)
并执行以下操作:
它读取r
的值并将f
应用于该值,产生(a',b)
。 然后用新值a'
更新r
,而b
是返回值。 这种读写访问是自动完成的。
当然,只有通过atomicModifyIORef
完成对r
的所有访问时,这种原子性才有效。 请注意,您可以通过查看来源 [1] 找到此信息。
[1] https://hackage.haskell.org/package/base-4.12.0.0/docs/Data-IORef.html#v:atomicModifyIORef
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.