Подтвердить что ты не робот

Почему тот же самый код выполняется быстрее в потоке?

Рассмотрим этот очень простой фрагмент кода:

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 ms на моем ПК. Теперь, если я пишу один и тот же код, используя только другой поток:

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 ms! (Скомпилирован в Delphi XE с активной конфигурацией Release) Я заметил ~ 25% усиления в потоке независимо от количества итераций, которые у меня есть. Почему это так? Не должны ли быть одинаковые результаты?

EDIT: После дальнейших исследований я обнаружил, что, вероятно, причиной этого является ОС Windows 7. На машине Windows 7 простой цикл в основном потоке выполняется на ~ 25% медленнее, чем версия async! Я даже пытался запустить этот же проект на том же ПК с Windows 7 с использованием режима Windows XP, а затем оба результата были равны - ~ 3000 мс! Я полностью потерялся здесь... Что делает Windows 7 с основным потоком, что он медленнее?

4b9b3361

Ответ 1

Странно, но, возможно, это из-за некоторого смещения c.q. выравнивание.

Возможно, переменные в анонимном потоке правильно выровнены, а другие нет. Вы можете попытаться добавить некоторые фиктивные переменные для изменения в смещение или если у вас есть Delphi XE2, попробуйте выполнить несколько выравнивание кода.