Spinlock.exit有或没有内存屏障

时间:2013-06-06 13:38:45

标签: c# .net memory-barriers

由于记忆障碍对我来说是一个新概念我试图绕过他们所以我编写了以下测试程序(C#):

private static void Func1()
{
    SpinLock sl = new SpinLock();

    Action action = () =>
    {
        for (int i = 0; i < 100; i++)
        {
            bool lockTaken = false;
            sl.Enter(ref lockTaken);
            if (lockTaken)
                sl.Exit(true);
        }
    };

    Parallel.Invoke(action, action);
}

private static void Main(string[] arg)
{
    for (int i = 0; i < 10000; i++)
        Func1();
}

问题是关于Spinlock.Exit(true)函数。 true表示发出内存屏障以立即将退出操作发布到其他线程。

当传递false时,没有发出内存屏障,然后代码运行速度几乎快两倍。

如果操作对象在线程之间包含共享内存并且传递了false,它仍然是一个正确的程序吗? 为什么内存屏障要慢得多?

1 个答案:

答案 0 :(得分:3)

使用Exit(true)或Exit(false)代码是正确的,即使在IA64上也是如此。布尔参数concerns fairness。实际上,实现使用内存屏障指令来获得公平性。

小心从这种事情的琐碎基准中得出结论。通常情况下,琐碎的基准将使不公平的解决方案看起来像一个不折不扣的赢家。但是在一个更大的系统环境中,缺乏公平性有时可能会使一个试图取得进展的线程挨饿而造成重大损害。但有时候不公平会更好。这取决于具体情况。