2014-02-09 64 views
3

我想在多核虚拟机上测试多线程程序的线程执行情况。我写了它的C#代码:关于多核进程怪异结果的多线程

class Program 
{ 
    public static int fib(int n) 
    { 
     if (n < 2) 
      return n; 

     return fib(n-1)+fib(n-2); 
    } 

    public static void execution(object n) 
    { 
     int STEP = 40; 
     var start = DateTime.Now; 
     int value = fib(STEP); 
     var end = DateTime.Now; 

     Console.WriteLine(string.Format("threads: {0}, time : {1}, start: {2}, end: {3}", n, end.Subtract(start).TotalSeconds, 
      start, end)); 
    } 

    static void Main(string[] args) 
    { 
     int[] threads = {1, 2, 4, 8, 16}; 

     for(int j=0; j<5; ++j) 
     { 
      for (int i = 0; i < threads[j]; ++i) 
      { 
       var thread = new Thread(Program.execution); 
       thread.Start(threads[j]); 
      } 
      Thread.Sleep(60000); 
     } 
    } 

,这是我

线程的结果:1,时间:4.2177734,开始:2014年2月8日下午七点30分13秒,结束:2/8/2014 7:30:18 PM

thread:2,time:4.1015625,start:2014/2/8 7:31:13 PM结束:2014/2/8 7:31:17 PM

thread:2,time:4.2441407,start:2014/2/8 7:31:13,结束于:2014/2/8 7:31:18 PM

的主题:4,时间:2.0351562,开始:2014/2/8 7:32:13,结束:2014/2/8 7:32:15

线程:4,时间:2.0527343,开始: 2014年2月8日下午7时32分13秒,结束:2014年2月8日下午7点32分15秒

线程:4,时间:2.0869141,开始:2014年2月8日下午7时32分13秒,结束于2014年2月8日7:32:15

线程:4,时间:2.0898437,开始时间:2014/2/8 7:32:13 PM结束时间:2014/2/8 7:32 :15 PM

线程:8,时间:3.34375,启动:2014年2月8日下午7时33分13秒,结束:2014年2月8日下午7点33分17秒

线程:8,时间:3.381836,开始:2014/2/8 7:33:13,结束:2014/2/8 7:33:17

线程:8,时间:3.3066406,开始:2014年2月8日下午7时33分14秒,结束:2014年2月8日下午7点33分17秒

线程:8,时间:3.2451172,开始:2014年2月8日7时33分14秒PM,结束:2014年2月8日下午7点33分17秒

线程:8,时间:3.4560547,启动:2014年2月8日下午7点33分13秒,结束:2014年2月8日7: 33:17 PM

线程:8,时间:3.5029296,开始日期:2014/2/8 7:33:13,结束日期:2014/2/8 7:33:17 PM

线程:8,时间:3.2841796,启动:2014年2月8日下午7点33分十四秒,结束:2014年2月8日下午7点33分17秒

线程:8,时间:3.4160157,开始:2014年2月8日下午7时33分14秒,结束:2014年2月8日下午7点33分17秒

主题:16,时间:5.9921875,开始:2014年2月8日七时34分14秒下午,结束:2014年2月8日下午7时34分20秒

主题:16,时间:6.4404297,开始:2014年2月8日下午7时34分14秒,结束:2014年2月8日7: 34:20 PM

线程:16,时间:5.3896484,开始日期:2014/2/8 7:34:15 PM结束日期:2014/2/8 7:34:20 PM

主题:16,时间:5.9658203,开始:2014年2月8日下午7点34分十四秒,结束:2014年2月8日下午7时34分20秒

主题:16,时间:5.9873047,开始:2014年2月8日下午7时34分14秒,结束:2014年2月8日下午7点34分20秒

主题:16,时间:6.2226563,开始:2014年2月8日7:34: 14 PM,结束日期:2014/2/8 7:34:20 PM

线程:16,时间:6。1552735,开始:2014/2/8 7:34:14,结束:2014/2/8 7:34:20

线程:16,时间:6.5576172,开始时间:2014/2/8 7: 34:14 PM,结束日期:2014/2/8 7:34:20

线程:16,时间:6.5273437,开始日期:2014/2/8 7:34:14 PM,结束日期:2/8/2014下午7点34分20秒

主题:16,时间:6.2529297,开始:2014年2月8日下午七点34分14秒,结束:2014年2月8日下午7点34分20秒

线程:16,时间:6.2958984,开始日期:2014/2/8 7:34:14,结束日期:2014/2/8 7:34:20

线程:16,时间:5.8544922,开始:2014/2/8 7:34:15,结束:2014/2/8 7:34:20

线程:16,时间:6.3886719,开始: 2/8/2014 7:34:14 PM结束:2014/2/8 7:34:20 PM

线程:16,时间:5.7089844,开始日期:2014/2/8 7:34:15 PM ,结束日期:2014/2/8 7:34:20

线程:16,时间:6.7207031,开始日期:2014/2/8 7:34:14结束时间:2014/2/8 7:34 :20 PM

线程:16,时间:6.0742188,启动:2014年2月8日下午7点34分14秒,结束:2014年2月8日下午7点34分21秒

请注意,我正在4核Windows 7虚拟机上运行程序。

对我来说没什么意义的是,当我有4个线程同时运行时,每个线程比计算1或2个线程时花费的时间少。

有人可以在这里解释吗?

回答

1

操作系统为您的每个线程提供一定的CPU运行时间。每个线程必须在队列中等待才能执行,随着线程数量的增加,此等待时间会变得更长。另一方面,每个线程将获得更少的执行时间。这在虚拟多核环境中会更明显,因为没有足够的物理内核来同时执行线程。另外,您应该考虑线程之间的上下文切换具有随着线程数量增加而增加的成本。因此,请避免在没有使用的情况下在应用程序上运行多个线程

3

这可能是因为优化程序没有真正实现它,直到你到达那里。尝试添加一些调用,首先将它调整到程序的开头,以获得更一致的结果。我只有一个双核心,所以我得到了与你展示的结果截然不同的结果,所以我不能更精确。

for (int r = 0; r < 20; r++) 
     fib(40); 
2

这是一个复杂的分析。如前所述,CPU为每个处理器提供时间片,而且您将受JIT进行优化,但更有可能在4个线程中,CPU能够以最佳速率平衡时间片和线程上下文切换。我敢肯定,由于许多事情不受你们的控制,这些结果会因每台机器而大幅变化。