Ответить на комментарий

Давай сделаем это медленно

Декабрь 8, 2012 — Шарахов А.П.

Внимательный читатель наверняка заметил, что я еще ни разу не упомянул об ассемблерных вставках. Почему? На мой взгляд, в их применении нет никакой выгоды.

Во-первых, практически все необходимые программисту команды процессора либо доступны на языках высокого уровня, либо могут быть успешно сэмулированы (см., например, Эмуляция операторов SAR, ROR, ROL в Delphi).

Во-вторых, ассемблерные вставки затрудняют сопровождение и анализ кода. Уж лучше изменить алгоритм или, в крайнем случае, полностью переписать нагруженные процедуры на ассемблере.

В-третьих, ассемблерные вставки уменьшают возможности оптимизации кода компилятором. Например, из-за них компилятор может разместить часто используемые переменные в оперативной памяти, а не в регистрах, и вместо прироста производительности будет получен совершенно противоположный результат.

Рассмотрим это подробнее на примере функции MulRol, которая в цикле выполняет умножение (имитация полезной работы) и вращение данных (имитация необходимости ассемблерной вставки). Ниже приведены четыре различных варианта функции: полностью ассемблерный вариант, вариант на Pascal с эмуляцией, вариант на Pascal с вызовом подпрограммы на ассемблере, вариант на Pascal с ассемблерной вставкой.

function MulRolAsm(count, mul, rol: integer): integer;
asm
  test eax, eax
  jle @done
@loop:
  imul edx, edx, $BCEBCAD
  rol edx, cl
  sub eax, 1
  jg @loop
@done:
  mov eax, edx
  end;
 
function MulRolPas(count, mul, rol: integer): integer;
var
  rol2, temp: integer;
begin;
  rol2:=-rol;
  while count>0 do begin;
    mul:=mul * $BCEBCAD;
    temp:=mul shr rol2; mul:=mul shl rol; mul:=mul or temp; //mul:=mul ROL rol;
    dec(count);
    end;
  Result:=mul;
  end;
 
function MulRolMix(count, mul, rol: integer): integer;
begin;
  while count>0 do begin;
    mul:=mul * $BCEBCAD;
    asm
      mov edx, mul
      mov ecx, rol
      rol edx, cl
      mov mul, edx
      end;
    dec(count);
    end;
  Result:=mul;
  end;
 
function rol32(value, shift: longint): longint;
asm
  mov ecx, edx
  rol eax, cl
  end;
 
function MulRolCall(count, mul, rol: integer): integer;
begin;
  while count>0 do begin;
    mul:=mul * $BCEBCAD;
    mul:=rol32(mul, rol);
    dec(count);
    end;
  Result:=mul;
  end;
 
procedure TForm1.Button1Click(Sender: TObject);
type
  TMulRol= function(count, mul, rol: integer): integer;
const
  f: array[1..4] of TMulRol= (MulRolAsm, MulRolPas, MulRolCall, MulRolMix);
  n: array[low(f)..high(f)] of string= ('Asm', 'Pas', 'Call', 'Mix');
var
  r: array[low(f)..high(f)] of integer;
  t: array[low(f)-1..high(f)] of cardinal;
  i: integer;
begin;
  t[low(f)-1]:=GetTickCount;
  for i:=low(f) to high(f) do begin;
    r[i]:=f[i](1234567890, 123, 8);
    t[i]:=GetTickCount;
    end;
  for i:=low(f) to high(f) do
    Memo1.Lines.Add(Format('%d   %d   %s', [r[i], t[i]-t[i-1], n[i]]));
  end;

Мне пришлось немного изменить код эмуляции вращения по сравнению с кодом, приведенным в указанной выше статье, для того, чтобы время работы этого варианта заметно отличалось от варианта с вызовом подпрограммы. После этого места распределились следующим образом:

  Result     Time   Function
=============================
-277667881   1641   Asm
-277667881   2578   Pas
-277667881   2875   Call
-277667881   5765   Mix
=============================

на главную

Ответить

  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Доступны HTML теги: <h1> <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Строки и параграфы переносятся автоматически.
  • You can enable syntax highlighting of source code with the following tags: <pre>, <code>, <asm>, <c>, <cpp>, <delphi>, <drupal5>, <drupal6>, <java>, <javascript>, <php>, <python>, <ruby>, <mytext>. Beside the tag style "<foo>" it is also possible to use "[foo]".

Подробнее о форматировании

CAPTCHA
Ведите текст с изображения. (вводить еще раз после предпросмотра а то не добавится комментарий)
Image CAPTCHA
Copy the characters (respecting upper/lower case) from the image.