C# 为什么我要将一个CPU绑定到一个比多个CPU执行速度快得多的多线程程序中?

C# 为什么我要将一个CPU绑定到一个比多个CPU执行速度快得多的多线程程序中?,c#,multithreading,C#,Multithreading,我正在编写一个测试程序来启动两个线程,如下所示 当我使用Process.ProcessorAffinity绑定来限制仅使用1个CPU时,程序需要45.8683742秒来执行,CPU 2几乎没有时间在这里使用操作系统内核程序 当我使用Process.ProcessorAffinity绑定来限制仅使用2个CPU时,程序需要67.733864秒来执行,CPU需要1,2秒,他们几乎没有时间在这里使用操作系统内核程序 当我使用Process.ProcessorAffinity绑定来限制仅使用3个CPU

我正在编写一个测试程序来启动两个线程,如下所示

当我使用Process.ProcessorAffinity绑定来限制仅使用1个CPU时,程序需要45.8683742秒来执行,CPU 2几乎没有时间在这里使用操作系统内核程序

当我使用Process.ProcessorAffinity绑定来限制仅使用2个CPU时,程序需要67.733864秒来执行,CPU需要1,2秒,他们几乎没有时间在这里使用操作系统内核程序

当我使用Process.ProcessorAffinity绑定来限制仅使用3个CPU时,程序需要116.8519694秒才能执行,而它们所在的CPU 1、2、3占用了操作系统内核程序更多的时间

当我使用Process.ProcessorAffinity绑定来限制仅使用8个CPU时,程序需要132.9382714秒来执行,并且它们所在的所有CPU占用了操作系统内核程序更多的时间

我不知道发生了什么,有人能解释一下吗

    class Program
{
    private static long counter = 0;
    public static void Main()
    {
        //Process.GetCurrentProcess().ProcessorAffinity = (IntPtr)7;

        Thread thread1 = new Thread(MyMethod);
        Thread thread2 = new Thread(MyMethod);

        thread1.Start();
        thread2.Start();

        Stopwatch sw = new Stopwatch();
        sw.Start();

        thread1.Join();
        thread2.Join();

        sw.Stop();

        Console.WriteLine($"Sum is {counter}");
        Console.WriteLine($"Total is {sw.Elapsed.TotalSeconds} Sec");

        Console.WriteLine("Press any key for continuing...");
        Console.ReadKey();
    }

    private static void MyMethod()
    {
        for (int index = 0; index < int.MaxValue; index++)
        { Interlocked.Increment(ref counter); }
    }
}
类程序
{
专用静态长计数器=0;
公共静态void Main()
{
//Process.GetCurrentProcess().ProcessorAffinity=(IntPtr)7;
螺纹螺纹1=新螺纹(MyMethod);
螺纹螺纹2=新螺纹(MyMethod);
thread1.Start();
thread2.Start();
秒表sw=新秒表();
sw.Start();
thread1.Join();
螺纹2.连接();
sw.Stop();
WriteLine($“Sum is{counter}”);
WriteLine($“总计为{sw.eassed.TotalSeconds}秒”);
Console.WriteLine(“按任意键继续…”);
Console.ReadKey();
}
私有静态void MyMethod()
{
对于(int index=0;index
根据您的评论,您试图用该计数器强制设置竞态条件。这里的问题是每个CPU都有一层层的缓存

虽然CPU和运行时不能保证存在竞态条件,但至少它最好不要主动地导致竞态条件。几乎没有什么事情能像hte 3层缓存中的任何一层那样快速地导致它们不同步

例如,如果Core 1更改其第1层缓存中计数器的值,则更改将集中传播到第3层缓存,然后向上传播到每个Core第1层缓存


由于操作是
counter=counter+1
,因此仍然存在竞争条件的空间。虽然您认为该操作将纯粹受CPU限制,但缓存的刷新实际上会强制它受内存限制。

根据您的评论,您试图用该计数器强制执行竞争条件。这里的问题是每个CPU都有一层层的缓存

虽然CPU和运行时不能保证存在竞态条件,但至少它最好不要主动地导致竞态条件。几乎没有什么事情能像hte 3层缓存中的任何一层那样快速地导致它们不同步

例如,如果Core 1更改其第1层缓存中计数器的值,则更改将集中传播到第3层缓存,然后向上传播到每个Core第1层缓存


由于操作是
counter=counter+1
,因此仍然存在竞争条件的空间。虽然您认为该操作将纯粹受CPU限制,但缓存的刷新实际上会迫使它受内存限制。

您的功能毫无意义,尤其是在多任务测试中。请向我们提供实际操作,以便我们可以告诉您多线程是否有希望加快执行。我知道MyMethod将是一种竞争条件,我的意图是模拟大量计算工作。@Christopher我已更改MyMethod()使用Interlocated.Increment方法来避免竞争条件,并更新我的测试程序和任务管理器的CPU使用情况。我也得到了同样的结果。你的行为毫无意义,尤其不是为了多任务测试。请向我们提供实际操作,以便我们可以告诉您多线程是否有希望加快执行。我知道MyMethod将是一种竞争条件,我的意图是模拟大量计算工作。@Christopher我已更改MyMethod()使用Interlocated.Increment方法来避免竞争条件,并更新我的测试程序和任务管理器的CPU使用情况。我得到了同样的结果。