我正在尝试在多核虚拟机上测试多线程程序的线程执行。我为它编写了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,开始时间:2/8/2014 7:30:13 PM,结束时间:2/8/2014 7:30:18 PM
主题:2,时间:4.1015625,开始时间:2/8/2014 7:31:13 PM,结束时间:2/8/2014 7:31:17 PM
主题:2,时间:4.2441407,开始时间:2/8/2014 7:31:13 PM,结束时间:2/8/2014 7:31:18 PM
主题:4,时间:2.0351562,开始时间:2/8/2014 7:32:13 PM,结束时间:2/8/2014 7:32:15 PM
主题:4,时间:2.0527343,开始时间:2/8/2014 7:32:13 PM,结束时间:2/8/2014 7:32:15 PM
主题:4,时间:2.0869141,开始时间:2/8/2014 7:32:13 PM,结束时间:2/8/2014 7:32:15 PM
主题:4,时间:2.0898437,开始时间:2/8/2014 7:32:13 PM,结束时间:2/8/2014 7:32:15 PM
主题:8,时间:3.34375,开始时间:2/8/2014 7:33:13 PM,结束时间:2/8/2014 7:33:17 PM
主题:8,时间:3.381836,开始时间:2/8/2014 7:33:13 PM,结束时间:2/8/2014 7:33:17 PM
主题:8,时间:3.3066406,开始时间:2/8/2014 7:33:14 PM,结束时间:2/8/2014 7:33:17 PM
主题:8,时间:3.2451172,开始时间:2/8/2014 7:33:14 PM,结束时间:2/8/2014 7:33:17 PM
主题:8,时间:3.4560547,开始时间:2/8/2014 7:33:13 PM,结束时间:2/8/2014 7:33:17 PM
主题:8,时间:3.5029296,开始时间:2/8/2014 7:33:13 PM,结束时间:2/8/2014 7:33:17 PM
主题:8,时间:3.2841796,开始时间:2/8/2014 7:33:14 PM,结束时间:2/8/2014 7:33:17 PM
主题:8,时间:3.4160157,开始时间:2/8/2014 7:33:14 PM,结束时间:2/8/2014 7:33:17 PM
主题:16,时间:5.9921875,开始时间:2/8/2014 7:34:14 PM,结束时间:2/8/2014 7:34:20 PM
主题:16,时间:6.4404297,开始时间:2/8/2014 7:34:14 PM,结束时间:2/8/2014 7:34:20 PM
主题:16,时间:5.3896484,开始时间:2/8/2014 7:34:15 PM,结束时间:2/8/2014 7:34:20 PM
主题:16,时间:5.9658203,开始时间:2/8/2014 7:34:14 PM,结束时间:2/8/2014 7:34:20 PM
主题:16,时间:5.9873047,开始时间:2/8/2014 7:34:14 PM,结束时间:2/8/2014 7:34:20 PM
主题:16,时间:6.2226563,开始时间:2/8/2014 7:34:14 PM,结束时间:2/8/2014 7:34:20 PM
主题:16,时间:6.1552735,开始时间:2/8/2014 7:34:14 PM,结束时间:2/8/2014 7:34:20 PM
主题:16,时间:6.5576172,开始时间:2/8/2014 7:34:14 PM,结束时间:2/8/2014 7:34:20 PM
主题:16,时间:6.5273437,开始时间:2/8/2014 7:34:14 PM,结束时间:2/8/2014 7:34:20 PM
主题:16,时间:6.2529297,开始时间:2/8/2014 7:34:14 PM,结束时间:2/8/2014 7:34:20 PM
主题:16,时间:6.2958984,开始时间:2/8/2014 7:34:14 PM,结束时间:2/8/2014 7:34:20 PM
主题:16,时间:5.8544922,开始时间:2/8/2014 7:34:15 PM,结束时间:2/8/2014 7:34:20 PM
主题:16,时间:6.3886719,开始时间:2/8/2014 7:34:14 PM,结束时间:2/8/2014 7:34:20 PM
主题:16,时间:5.7089844,开始时间:2/8/2014 7:34:15 PM,结束时间:2/8/2014 7:34:20 PM
主题:16,时间:6.7207031,开始时间:2/8/2014 7:34:14 PM,结束时间:2/8/2014 7:34:20 PM
主题:16,时间:6.0742188,开始时间:2/8/2014 7:34:14 PM,结束时间:2/8/2014 7:34:21 PM
请注意我在4核Windows 7虚拟机上运行该程序。
对我来说没有意义的是,当我有4个线程同时运行时,每个线程的计算时间比我同时运行1或2个线程的时间要短。
有人可以在这里解释一下吗?
答案 0 :(得分:2)
这可能是因为优化器在你到达那里之前并没有真正达到它的步伐。尝试添加一些调用,首先将其变形到程序的开头,以获得更一致的结果。我只有一个双核,所以我得到的结果与你所展示的结果截然不同,所以我不能更精确。
for (int r = 0; r < 20; r++)
fib(40);
答案 1 :(得分:1)
操作系统为您的每个线程提供一定量的CPU运行时间。每个线程都必须在队列中等待才能执行,随着线程数量的增加,这个等待时间会变长。另一方面,每个线程将获得更少的量子时间来执行。这在虚拟多核环境中将更加明显,因为没有足够的物理内核可以同时执行您的线程。
此外,您应该考虑线程之间的上下文切换,其成本会随着线程数量的增加而增加。因此,避免在不使用
的情况下在应用程序上运行多个线程答案 2 :(得分:1)
这是一个复杂的分析。如前所述,CPU为每个处理器提供时间片,并且您需要对JIT进行优化,但更有可能在4个线程上,CPU能够以最佳速率为您的程序平衡时间片和线程上下文切换。我敢肯定,由于您无法控制很多事情,这些结果会因机器而异。