アトミックな数値

Java並行処理読んでて出てきたアトミックなクラス(java.util.concurrent.atomic.*).最初Vectorみたいに全部synchronizedがついてるのかと思ってたら勿論そんなわけじゃなくて,CPU命令を使ってアトミックに操作してるらしい(Atomicってついてるんだから当たり前か).Javaの場合はUnsafe経由でネイティブ操作だけど,D言語は元々ネイティブな言語なのでuintはすぐできた.

struct AtomicUInt
{
    uint value;

    uint opPostInc()
    {
        while (true) {
            uint oldValue = value;
            uint newValue = value + 1;
            if (CAS(&value, value, newValue))
                return oldValue;
        }
    }

    /* other methods */

    string toString()
    {
        return text(value);
    }
}

後は実行してみる.

void main()
{
    AtomicUInt num;
    void test1() { foreach (unused; 0..1000_000) num++; }

    Thread[] threads = new Thread[5];

    foreach (ref thread; threads) thread = new Thread(&test1);
    foreach (ref thread; threads) thread.start;
    foreach (ref thread; threads) thread.join;

    writeln(num);
}

AtomicUIntをuintにすると値がおかしくなる.uintがすぐできたのは,std.atomics.CASがuintを対象にしているからで,他の型はasmでも使って書いてやらないと行けない(これくらいならレジスタ変更で何とかなりそう?).まぁなんにせよこの辺は強化して欲しいなぁと思う所.SeanのConcurrency APIが入る時に強化されるんだろうか…