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