Генерация высококачественного кода для программ на СИ
Страница 5. Методы оптимизации. Часть 3


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

  --------------------------------------------------------------¬
  ¦РИСУНОК 2: Простой цикл        ¦
  +-------------------------------------------------------------+
  ¦Исходный текст на Си BORLAND  METAWARE   ¦
  ¦      Turbo C 1.5   High C 1.4 ¦
  ¦(x) - врем. циклы      (125)    (87)     ¦
  +-------------------------------------------------------------+
  ¦k5 = 10000;     mov  j5,0     mov  j5,0  ¦
  ¦j5 = 0;    mov  k5,10000 mov  k5,10000   ¦
  ¦do {       @10:     L00e3:     ¦
  ¦    k5 = k5 - 1;     mov  AX,k5    dec  k5    ¦
  ¦    j5 = j5 + 1;     dec  AX  inc  j5    ¦
  ¦    i5 = (k5 * 3) /  mov  k5,AX    mov  AX,j5 ¦
  ¦  (j5 * constant5);  mov  AX,j5    mov  SI,AX ¦
  ¦} while (k5 > 0);    inc  AX  sal  SI,2  ¦
  ¦      mov  j5,AX    add  SI,AX ¦
  ¦      mov  AX,k5    mov  AX,k5 ¦
  ¦      imul AX,AX,3  mov  DX,AX ¦
  ¦      push AX  add  DX,DX ¦
  ¦      mov  AX,j5    add  DX,AX ¦
  ¦      imul AX,AX,5  xchg AX,DX ¦
  ¦      mov  BX,AX    cwd   ¦
  ¦      pop  AX  idiv SI    ¦
  ¦      cwd      mov  I5,AX ¦
  ¦      idiv BX  cmp  k5,0  ¦
  ¦      mov  i5,AX    jnle L00e3 ¦
  ¦      cmp  k5,0      ¦
  ¦      jg   @10       ¦
  +-------------------------------------------------------------+
  ¦  MICROSOFT       WATCOM       ¦
  ¦   C 5.0     C 6.0        ¦
  ¦    (46)      (91)        ¦
  +-------------------------------------------------------------+
  ¦  mov  j5,10000  mov  j5,0     ¦
  ¦  mov  k5,0      mov  DI,10000      ¦
  ¦  mov  CX,30000 L4    dec  DI       ¦
  ¦  sub  SI,SI     imul AX,DI,3       ¦
  ¦ $0265:     inc  j5       ¦
  ¦  sub  CX,3      imul BX,j5,5       ¦
  ¦  add  SI,5      cwd      ¦
  ¦  mov  AX,CX     idiv BX       ¦
  ¦  cwd       mov  i5,AX    ¦
  ¦  idiv SI   test DI,DI    ¦
  ¦  mov  DI,AX     jg   L4       ¦
  ¦  or   CX,CX         ¦
  ¦  jg   $0265         ¦
  ¦  mov  i5,DI         ¦
  +-------------------------------------------------------------+
  ¦ Компилятор  Microsoft C 5.0 выполнил снижение мощности на   ¦
  ¦ константном  выражении  и  разместил  в   регистрах   все   ¦
  ¦ переменные  внутри  простого  цикла,  включая вычисляемое   ¦
  ¦ значение i5. Высокая степень проведенного  анализа  цикла   ¦
  ¦ демонстрируется тем, что заключительные состояния k5 и j5   ¦
  ¦ были  определены  заранее  компилятором,  а  не позже, во   ¦
  ¦ время выполнения.        ¦
  L--------------------------------------------------------------


 "Вынесение инвариантного (неизменяющегося) кода" - один из путей ускорения
 циклов, заключающийся в вынесении выражений за пределы цикла, если
 значения, ими вычисляемые, являются неизменными во время выполнения цикла.
 Если инвариантный код выносится из следующего цикла:
  unsigned char i,j,k,v,x;
  for (i = 0; i < v; i++)
     x = i * (j+k);

 его логический эквивалент будет:
  T1 = j + k;
  for(i = 0; i < v; i++)
     x = i * T1;

  --------------------------------------------------------------¬
  ¦РИСУНОК 3: Вынесение инвариантного кода - Microsofr C 5.0    ¦
  +-------------------------------------------------------------+
  ¦Исходный текст на Си MICROSOFT     COMPUTER INNOVATIONS ¦
  ¦      C 5.0    C86Plus 1.10    ¦
  +-------------------------------------------------------------+
  ¦for(i4=0;i4<=2;i4++)   sub  SI,SI     mov  i4,0    ¦
  ¦  ivector2[i4] =j*k;   mov  AX,j      jmp  L44@2   ¦
  ¦        imul k      L9@2:      ¦
  ¦        mov  [BP-4],AL mov  AX,j    ¦
  ¦     $L20007:     imul k  ¦
  ¦        mov  AL,[BP-4] mov  SI,i4   ¦
  ¦    mov  ivector2[SI],AL       ¦
  ¦        inc  SI  mov ivector2[SI],AL¦
  ¦        cmp  SI,2      inc  i4      ¦
  ¦        jle  $L20007    L44@2:      ¦
  ¦        mov  i4,SI     cmp  i4,2    ¦
  ¦        jle  L9@2    ¦
  +-------------------------------------------------------------+
  ¦ Вынесение  инвариантного  кода  уменьшает время выполнения  ¦
  ¦ цикла путем вынесения  неизменяющихся  выражений  из  тела  ¦
  ¦ цикла.  В  отличие  от  Computer Innovations C86Plus 1.10,  ¦
  ¦ компилятор Microsoft C 5.0 успешно выносит выражение j * h  ¦
  ¦ за пределы цикла, так что оно выполняется только один раз,  ¦
  ¦ вместо того, чтобы выполняться на каждой итерации цикла.    ¦
  L--------------------------------------------------------------

 
« Предыдущая статья   Следующая статья »