【问题标题】:Why same code executes faster in the thread?为什么相同的代码在线程中执行得更快?
【发布时间】:2012-02-13 22:01:19
【问题描述】:

考虑一下这段非常简单的代码:

uses Diagnostics;

const
  ITER_COUNT = 100000000;

procedure TForm1.btn2Click(Sender: TObject);
var
  val: Double;
  i: Integer;
begin
  sw := TStopwatch.StartNew;

  val := 1;
  for i := 0 to ITER_COUNT - 1 do
  begin
    val := val + i;
    val := val - i;
    val := val * 10;
    val := val / 10;
  end;

  sw.Stop;

  mmo1.Lines.Add(Format('Simple completed in %D ms. Result: %G',
    [sw.ElapsedMilliseconds, val]));
end;

这个简单的循环在我的电脑上以 4027 毫秒执行。现在,如果我编写相同的代码,只使用不同的线程:

procedure TForm1.btn3Click(Sender: TObject);
begin
  sw := TStopwatch.StartNew;
  TThread.CreateAnonymousThread(
    procedure
    var
      val: Double;
      i: Integer;
    begin
      val := 1;
      for i := 0 to ITER_COUNT- 1 do
      begin
        val := val + i;
        val := val - i;
        val := val * 10;
        val := val / 10;
      end;

      sw.Stop;

      TThread.Queue(nil, procedure
        begin
          mmo1.Lines.Add(Format('Async completed in %D ms. Result: %G',
            [sw.ElapsedMilliseconds, val]));
        end);
    end
  ).Start;
end;

这个方法在2910毫秒内执行相同但在不同线程中的方法! (在 Delphi XE 中编译,发布配置处于活动状态)无论我有多少次迭代,我注意到线程中的增益约为 25%。为什么会这样?不应该是一样的结果吗?

编辑: 经过进一步调查,我发现这可能是 Windows 7 操作系统的原因。在 Windows 7 机器上,主线程中的简单循环执行速度比异步版本慢约 25%!我什至尝试使用 Windows XP 模式在同一台 Windows 7 PC 上运行相同的项目,然后两个结果相等 - ~3000 毫秒!我完全迷失了……Windows 7 对主线程的处理速度变慢了?

【问题讨论】:

  • 无法重现,我的笔记本电脑的执行时间相同(~2600 毫秒)。
  • 对我来说也没有什么不同。 1947 和 1949 毫秒在我的机器上,但由于我仍在使用 Delphi 5 作为我的主要开发环境,因此我学到了一些新东西,为此 +1。
  • 您在什么操作系统上进行了测试?
  • @Linas Win7 Ultimate SP1 64 位,CPU Core i3 M380(2 个物理核心/4 个逻辑核心)
  • 极不可能与操作系统版本有关。操作系统在循环内无关紧要。

标签: delphi delphi-xe


【解决方案1】:

确实很奇怪,但也许是因为某些偏移量 c.q。对齐。

也许匿名线程中的变量正确对齐,而另一个没有。 您可以尝试添加一些虚拟变量以更改为偏移量,或者如果您有Delphi XE2,请尝试一些不同的code alignment

【讨论】:

  • 我设法使用虚拟变量(在某些测试中约为 5000 毫秒)进一步减慢了第一个版本的速度,不能使其速度超过 ~4000 毫秒...但这不会影响异步版本...
  • @Linas 确保val 始终在 8 字节边界上对齐。例如,通过调用 GetMem 而不是在堆栈上分配它。
  • @DavidHeffernan 成功了。如果我手动将Double 变量与GetMem 对齐,循环将按预期执行。问题是为什么 Delphi 在单独的匿名线程中正确地做到了这一点,而不是在主线程中?
  • @Linas 这只是运气。
  • 在我看来,这是 Delphi 浮点的一个大问题。我不知道为什么编译器没有正确对齐浮点堆栈变量。对于编译器供应商来说,这是微不足道的。他们懒得去做的事实让我们的生活变得非常艰难。
猜你喜欢
  • 1970-01-01
  • 2018-12-25
  • 1970-01-01
  • 2012-06-29
  • 1970-01-01
相关资源
最近更新 更多