1

由于内存屏障对我来说是一个新概念,我试图了解它们,所以我编写了以下测试程序(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,它仍然是一个正确的程序吗?为什么内存屏障这么慢?

4

1 回答 1

3

代码对于 Exit(true) 或 Exit(false) 都是正确的,即使在 IA64 上也是如此。布尔参数涉及公平。它只是碰巧实现使用内存屏障指令来获得这种公平性。

小心从这类事情的琐碎基准中得出结论。通常,微不足道的基准会使不公平的解决方案看起来像一个不折不扣的赢家。但是在更大的系统环境中,缺乏公平性有时会通过使试图取得进展的线程之一饿死而造成重大损害。但有时不公平会更好。这取决于上下文。

于 2013-06-06T21:12:13.123 回答