为什么具有2个线程的8个进程每个创建的负载比具有16个线程的进程多?

Man*_*uel 4 c# multithreading

我有一个简单的程序,它启动n个线程并在每个线程上创建一些负载.如果我只启动一个线程,则一个核心获得大约100%的负载.如果我用16个线程(这意味着每个核心一个线程)启动一个进程,我只能获得大约80%的负载.如果我用2个线程启动8个进程(这仍然意味着每个核心一个线程),我得到大约99%的负载.我在这个样本中没有使用任何锁定.

这种行为的原因是什么?据我所知,如果有100个线程正在工作,那么负载会下降,因为操作系统必须安排很多.但在这种情况下,只有核心数量的线程.

情况更糟(至少对我而言).如果我在循环中添加一个简单的thread.sleep(0),则一个进程和16个线程的负载增加到95%.

任何人都可以回答这个问题,或提供有关此特定主题的更多信息的链接吗?

一个进程16个线程

八个进程2线程

一个进程16个线程与thread.sleep(0)

//Sample application which reads the number of threads to be started from Console.ReadLine
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Enter the number of threads to be started");
            int numberOfThreadsToStart;

            string input = Console.ReadLine();

            int.TryParse(input, out numberOfThreadsToStart);
            if(numberOfThreadsToStart < 1)
            {
                Console.WriteLine("No valid number of threads entered. Exit now");
                Thread.Sleep(1500);
                return;
            }

            List<Thread> threadList = new List<Thread>();
            Stopwatch sw = Stopwatch.StartNew();
            for (int i = 0; i < numberOfThreadsToStart; i++)
            {
                Thread workerThread = new Thread(MakeSomeLoad);
                workerThread.Start();
                threadList.Add(workerThread);
            }

            while (true)
            {
                Console.WriteLine("I'm spinning... ");
                Thread.Sleep(2000);
            }
        }

        static void MakeSomeLoad()
        {
            for (int i = 0; i < 100000000; i++)
            {

                for (int j = 0; j < i; j++)
                {
                    //uncomment the following line to increase the load
                    //Thread.Sleep(0);
                    StringBuilder sb = new StringBuilder();
                    sb.Append("hello world" + j);
                }
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

Cod*_*aos 6

你的测试看起来很重.如果在一个进程中有16个线程,则GC将在该进程中运行更多,并且由于客户端GC不是并行的,因此会导致负载降低.即每个GC线程有16个垃圾生成线程.

另一方面,如果运行8个进程,每个进程有两个线程,则只有两个线程为每个GC线程生成垃圾,GC可以在这些进程之间并行工作.

如果您编写的测试产生的垃圾较少,并且直接使用更多的CPU,则可能会得到不同的结果.

(注意,这只是猜测,我没有运行你的测试,因为我只有一个双核CPU,不管你的结果如何)