简体   繁体   English

尝试捕获.NET中的内存重新排序

[英]Attempting to catch memory reordering in .NET

I have a slightly bizarre program in which I am attempting to catch some memory reordering in .NET: 我有一个有点奇怪的程序,我试图在其中捕获一些.NET中的内存重新排序:

private static volatile int x, y;
private static int b = -1;
private static int a = -1;

static void Main()
{
    Run(); 
}

public static void Run()
    {
        Random rand = new Random();
        var time = DateTime.Now;
        while ((a != 0 || b != 0))
        {
            int t1StartId = rand.Next(1, 10);
            int t2StartId = rand.Next(1, 10);

            Thread t1 = new Thread(RunOne);
            Thread t2 = new Thread(RunTwo);

            for (int i = 0; i <= 10; i++)
            {
                if (t1StartId == i)
                {
                    t1.Start();
                }

                if (t2StartId == i)
                {
                    t2.Start();
                }
            }

            t1.Join();
            t2.Join();
            x = 0;
            y = 0;
        }

        Console.WriteLine("Memory Reordered!!!!!!!!!!!!!!!!!!!!!");
        Console.WriteLine("Time Taken: {0}", DateTime.Now - time);
    }

    static void RunOne()
    {
        x = 1;
        a = y;
    }

    static void RunTwo()
    {
        y = 1;
        b = x;
    }
}

Now from the reading I have been doing ( here , here , here , here ), it *should be possible for both a and b to equal 0 after each thread has completed executing. 现在,根据我一直在做的阅读( 此处此处此处此处 ),*在每个线程完成执行之后,a和b都应该等于0。 Is anyone able to confirm this? 有人可以确认吗? Are any of my operations presenting a memory barrier under the scenes of which I am not aware of which would prevent reordering and thus keep the infinite loop going? 在我不知道的情况下,我的任何操作是否会出现内存障碍,从而阻止重新排序并因此导致无限循环继续?

I am running this on x86 CPU, which I suspect could also have impact on the result. 我在x86 CPU上运行此程序,我怀疑这也会对结果产生影响。

edit: 编辑:

So after running the program multiple times it is now getting out of the loop: 因此,在多次运行该程序之后,它现在退出了循环:

在此处输入图片说明

I'm still not convinced this is a result of memory reordering. 我仍然不相信这是内存重新排序的结果。

Second run: 第二轮:

在此处输入图片说明

So conclusive question! 如此结论性的问题! - Is this truly a result of memory reordering, or is it something else? -这确实是内存重新排序的结果,还是其他原因?

Yes, your example demonstrates memory reordering. 是的,您的示例演示了内存重新排序。 I could not reproduce it myself, but that's probably a result of my specific setup. 我自己无法复制它,但这可能是我特定设置的结果。

I will use a down arrow ↓ to represent a volatile read and an up arrow ↑ to represent a volatile write. 我将使用向下箭头↓表示易失性读取,使用向上箭头↑表示易失性写入。 Think of the arrow head as pushing away any other reads and writes. 可以将箭头想像成是其他读写操作。 The code that generates these memory fences is free to move around as long as no instruction goes up through a down arrow and down through an up arrow. 只要没有指令通过向下箭头和通过向上箭头向下,生成这些内存围栏的代码可以自由移动。 The memory fences (the arrows), however, are locked in place at the spot where they were originally declared in the code. 但是,内存栅栏(箭头)被锁定在代码中最初声明它们的位置。 So reproducing your code with the fences illustrated would look like this. 因此,使用所示的围栏来复制代码看起来像这样。

static void RunOne()
{
    ↑                 // volatile write fence
    x = 1;            
    var register = y; 
    ↓                 // volatile read fence
    a = register;
}

static void RunTwo()
{
    ↑                 // volatile write fence
    y = 1;
    var register = x;
    ↓                 // volatile read fence
    b = register;
}

So you can see that in RunOne the write to x and the read of y can be swapped legally. 因此,您可以看到在RunOne可以合法地交换对x的写入和对y的读取。 Similarly in RunTwo the write y and the read of x can be swapped legally as well. 同样,在RunTwoyx的读值也可以合法交换。

The fact that you are using the x86 architecture has no implication on this example because a volatile write followed by a volatile read is the only arrangement still allowed to be swapped in the x86's strong memory model. 使用x86体系结构的事实对该示例没有任何影响,因为在x86的强内存模型中,仍然允许交换易失性写入,然后进行易失性读取。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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