Почему один и тот же код выполняется быстрее в потоке? - PullRequest
10 голосов
/ 19 января 2012

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

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 7 в режиме Windows XP, и тогда оба результата были равны - ~ 3000 мс!Я полностью потерян здесь ... Что Windows 7 делает с основным потоком, что он медленнее?

1 Ответ

12 голосов
/ 19 января 2012

Действительно странно, но, возможно, это из-за некоторого выравнивания cq смещения.

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

...