27

誰かがどのように機能するか説明できますかatomicModifyIORef? 特に:

(1) ロックを待つか、競合が発生した場合に楽観的に試行および再試行しますか (のようにTVar)。
(2) の署名が の署名とatomicModifyIORef異なるのはなぜmodifyIORefですか? 特に、この余分な変数は何bですか?

編集: (2) に対する答えを見つけたと思います。つまり、b抽出する値です (必要ない場合は空にすることができます)。シングルスレッドプログラムでは、値を知ることは簡単ですが、マルチスレッドプログラムでは、関数が適用された時点での以前の値を知りたい場合があります。modifyIORefこれが、この余分な戻り値がない理由だと思います(modifyIORefこの戻り値を使用した使用法はおそらくatomicModifyIORefとにかく使用する必要があります。ただし、(1)への回答にはまだ興味があります。

4

2 に答える 2

34

ロックを待つか、競合が発生した場合 (TVar など) に楽観的に再試行しますか。

atomicModifyIORef は、基盤となるハードウェア アーキテクチャでロック命令を使用して、割り当てられた Haskell オブジェクトへのポインタをアトミックな方法でスワップします。

atomicModifyMutVar#x86 では、次のように Cmm でランタイム サービスとして実装されている cas 命令を使用します。

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 ではアトミック命令を使用できることがわかりますが、他のアーキテクチャでは異なるメカニズムが使用されます。ランタイムは再試行します。

于 2012-04-11T12:41:29.450 に答える
13

atomicModifyIORefr :: IORef aと 関数を取り、f :: a -> (a, b)次のことを行います。

の値を読み取り、この値にr適用fして、 を生成し(a',b)ます。次に、rが新しい値で更新され、 がa'戻りb値です。この読み取りおよび書き込みアクセスは、アトミックに行われます。

もちろん、この原子性は へのすべてのアクセスrが 経由で行われる場合にのみ機能しatomicModifyIORefます。ソース [1] を見ると、この情報を見つけることができることに注意してください。

[1] https://hackage.haskell.org/package/base-4.12.0.0/docs/Data-IORef.html#v:atomicModifyIORef

于 2012-04-11T09:21:20.627 に答える