简体   繁体   English

Haskell:“atomicModifyIORef”是如何工作的?

[英]Haskell: How does 'atomicModifyIORef' work?

Can someone explain how atomicModifyIORef works?有人可以解释atomicModifyIORef是如何工作的吗? In particular:特别是:

(1) Does it wait for a lock, or optimistically try and retry if there's contention (like TVar ). (1) 它是等待锁定,还是乐观地尝试并在存在争用时重试(如TVar )。
(2) Why is the signature of atomicModifyIORef different to the signature of modifyIORef ? (2) 为什么 atomicModifyIORef 的签名与atomicModifyIORef的签名modifyIORef In particular, what is this extra variable b ?特别是,这个额外的变量b是什么?

Edit: I think I've figured out the answer to (2), in that b is a value to be extracted (this can be empty if not needed).编辑:我想我已经找到了 (2) 的答案,因为b是要提取的值(如果不需要,它可以为空)。 In a single threaded program, knowing the value is trivial, but in a multithreaded program, one may want to know what the previous value was at the time of the function being applied.在单线程程序中,知道该值是微不足道的,但在多线程程序中,人们可能想知道在应用 function 时的先前值是什么。 I assume this is why modifyIORef doesn't have this extra return value (as such usages of modifyIORef with this return value probably should use atomicModifyIORef anyway. I'm still interested in the answer to (1) though.我认为这就是为什么modifyIORef没有这个额外的返回值(因为带有这个返回值的modifyIORef的用法可能无论如何都应该使用atomicModifyIORef 。不过我仍然对(1)的答案感兴趣。

Does it wait for a lock, or optimistically try and retry if there's contention (like TVar).它是等待锁定,还是乐观地尝试并在存在争用时重试(如 TVar)。

atomicModifyIORef uses an locking instruction on the underlying hardware architecture you're on, to swap the pointer to an allocated Haskell object in an atomic fashion. atomicModifyIORef 在您所在的底层硬件架构上使用锁定指令,以原子方式将指针交换到分配的 Haskell object。

On x86 it uses the cas intruction, exposed as a primitive to the language via atomicModifyMutVar# , which is implemented as a runtime service in Cmm as:在 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
...
}

That is, it will try to do the swap, and retry otherwise.也就是说,它将尝试进行交换,否则重试。

The implementation of cas as a primitive shows how we get down to the metal: 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;

So you can see that it is able to use an atomic instruction in Intel, on other architectures different mechanisms will be used.所以你可以看到它能够在 Intel 中使用原子指令,在其他架构上将使用不同的机制。 The runtime will retry.运行时将重试。

atomicModifyIORef takes a r:: IORef a and a function f:: a -> (a, b) and does the following: atomicModifyIORef采用r:: IORef a和 function f:: a -> (a, b)并执行以下操作:

It reads the value of r and applies f to this value, yielding (a',b) .它读取r的值并将f应用于该值,产生(a',b) Then the r is updated with the new value a' while b is the return value.然后用新值a'更新r ,而b是返回值。 This read and write access is done atomically.这种读写访问是自动完成的。

Of course this atomicity only works if all accesses to r are done via atomicModifyIORef .当然,只有通过atomicModifyIORef完成对r所有访问时,这种原子性才有效。 Note that you can find this information by looking at the source [1].请注意,您可以通过查看来源 [1] 找到此信息。

[1] https://hackage.haskell.org/package/base-4.12.0.0/docs/Data-IORef.html#v:atomicModifyIORef [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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM