【发布时间】:2012-08-10 04:27:06
【问题描述】:
我编写了一个 Win32 应用程序(在 Delphi-7 中,它是 32 位使用 TThread 类)来创建 100 个线程。每个线程在恢复时将连续(在循环中)增加与线程对象关联的 64 位计数器(因此不会锁定或共享数据)。
如果您让系统运行 10 到 15 秒然后停止,您应该会看到每个线程中的计数大致相同。但我观察到,81 个线程运行了 4 亿次以下的循环,其余的循环超过了 9.5 亿次。与最快的 21.11 亿相比,最慢的线程只有 2.3 亿。
根据 MSDN,抢占式多任务处理处于线程级别(而不是进程级别),因此我的每个线程都应该以循环方式获得其时间片。我在这里缺少什么,为什么会出现这种差异?
Edit1:机器配置:Intel i7 Quad Core 3.4GHz,超线程已开启(一次 8 个活动线程)。运行 Windows-7 64 位专业版(并且测试应用程序是 32 位)
Edit2(线程代码):测试应用程序是在启用优化且没有任何调试信息的情况下构建的。在 IDE 之外运行测试应用程序。
type
TMyThread = class(TThread)
protected
FCount: Int64;
public
constructor Create;
procedure Execute; override;
property Count: Int64 read FCount;
end;
{ TMyThread }
constructor TMyThread.Create;
begin
inherited Create(True);
FCount := 0;
end;
procedure TMyThread.Execute;
begin
inherited;
while not Terminated do
begin
Inc(FCount);
end;
end;
【问题讨论】:
-
你没有说你的计数器是如何放置在内存中的;我猜如果计数器形成一个实心数组,当它们增加计数器时可能会导致线程相互依赖。
-
您能否发布您的 TThread 派生类 dec。 +“执行”方法?我想试一试。如果您还没有尝试过,如果您在 IDE 之外运行应用程序会发生什么?另外,什么操作系统?
-
OK - W7 - 它在问题标题中这样说。 64 位还是 32 位?
-
@Serg - 你可能是对的,一些令人讨厌的错误共享与超出缓存线边界的线程集:(
-
如果线程增量计数器在一致的基础上神奇地一致在 10% 以内,我会感到震惊。混沌是线程与 CPU 微架构特性(如缓存、分支预测、虚拟内存和交换)以及 IO-bound 和 CPU-bound 线程的动态 CPU 负载相结合的本质。这不是 1980 年的 8 位无缓存 1mhz 微型 CPU。
标签: multithreading delphi winapi delphi-7 multitasking