Директива компилятора для раскрутки цикла

Предлагаю ввести директиву раскрутки цикла следующего вида:

{$LoopUnrolling}
For Var i:=0 to 9 do
  Метод();

Которая разматывает следующий за ней цикл в такой код:

Метод();
Метод();
Метод();
Метод();
Метод();
Метод();
Метод();
Метод();
Метод();
Метод();

Это позволяет ускорить программу многократно. Вот рабочий пример:

Uses System;

begin
  var DT := DateTime.Now;
  var a: Double;
  for Var i := 1 to 10000000 do
  begin
    a -= a * 0.99;
    for Var j := 1 to 19 do
    begin
      a += i * j;
    end;
  end;
  Console.WriteLine((DateTime.Now - DT).TotalMilliseconds);
  a := 0;
  DT := DateTime.Now;
  for Var i := 1 to 10000000 do
  begin
    a -= a * 0.99;
    a += i * 1;
    a += i * 2;
    a += i * 3;
    a += i * 4;
    a += i * 5;
    a += i * 6;
    a += i * 7;
    a += i * 8;
    a += i * 9;
    a += i * 10;
    a += i * 11;
    a += i * 12;
    a += i * 13;
    a += i * 14;
    a += i * 15;
    a += i * 16;
    a += i * 17;
    a += i * 18;
    a += i * 19;
  end;
  Console.WriteLine((DateTime.Now - DT).TotalMilliseconds);
  Console.ReadLine();
end.

На моём компьютере разница примерно в 2 раза.

  • За введение директивы
  • Против введения директивы

0 голосов

Лучше приведите мой последний пример, потому что тот что сейчас оптимизирует, и в итоге разница получается в 30 раз а не в 2. Потому что все присвоения кроме последнего стирает.

Сделано.

А *0.99 зачем убрали? Оно нужно чтоб на 100% быть уверенным что компилятор не заменит это на a := 0

Вернул.

Что ж, если большинство против введения раскрутки циклов, то это придётся делать вручную.