Модератор: Модераторы
anotherche писал(а): Код тестовой программы (просто длинный цикл с вещественными вычислениями), откомпилированный с одинаковыми опциями исполняется на 20%(atlon) - 100%(p4) медленней. Почему?

Это разница между чем и чем?...
Я правильно понял - один код был собран fpc 2.0.0 и fpc 1.010 и затем оба ипоняемых модуля были запущены на ПК с Atlon и ПК с P4 ?
program Test_PC;
uses crt,dos{,graph};
Var i,j,k, itnum : Longint;
    c,dT : double;
         {##################################################}
Function Time : double;
Var Ho,Mi,Se,Se1 : word; dH,dM,dS,dS1 : double;
begin
          GetTime(Ho,Mi,Se,Se1); dH:=Ho; dM:=Mi; dS:=Se; dS1:=Se1;
          Time:=(3600.0*dH +60.0*dM +dS +0.01*dS1); end;
           {########################################}
begin
itnum:=30;
WriteLn('###############       ','   Test of PC ,DOS','    ###############');
WriteLn('Time for PC 486        133 Mhz, Real   = ',16.53:15:9,'  Sec');
WriteLn('Time for PC PENTIUM    150 Mhz, Real   = ', 5.93:15:9,'  Sec');
WriteLn('Time for PC PENTIUM(1) 166 Mhz, Real   = ', 5.10:15:9,'  Sec');
WriteLn('Time for PC PENTIUM-2  233 Mhz, Real   = ', 4.61:15:9,'  Sec');
WriteLn('Time for PC Celeron    400 Mhz, Real   = ', 2.74:15:9,'  Sec');
WriteLn('Time for PC PENTIUM    225 Mhz, Real   = ', 2.69:15:9,'  Sec');
WriteLn('Time for PC Celeron    333 Mhz, Real   = ', 3.24:15:9,'  Sec');
WriteLn('Time for PC 486        133 Mhz, Protect= ',21.69:15:9,'  Sec');
WriteLn('Time for PC PENTIUM    150 Mhz, Protect= ',12.69:15:9,'  Sec');
WriteLn('Time for PC PENTIUM(1) 166 Mhz, Protect= ',11.64:15:9,'  Sec');
WriteLn('Time for PC PENTIUM-2  233 Mhz, Protect= ',10.11:15:9,'  Sec');
WriteLn('Time for PC Celeron    400 Mhz, Protect= ', 5.66:15:9,'  Sec');
WriteLn('Time for PC PENTIUM    225 Mhz, Protect= ', 5.33:15:9,'  Sec');
WriteLn('Time for PC Celeron    333 Mhz, Protect= ', 6.81:15:9,'  Sec');
WriteLn('Time for PC Athlon XP 1700 Mhz, Protect= ', 0.72:15:9,'  Sec');
WriteLn('                        Time for FREE PASCAL');
WriteLn('Time for PC Athlon    2000 Mhz, Protect= ', 0.160:15:9,'  Sec');
WriteLn('Time for PC Intel     3150 Mhz, Protect= ', 0.118:15:9,'  Sec');
WriteLn('Time for PC Intel     3300 Mhz, Protect= ', 0.113:15:9,'  Sec');
WriteLn('Time for PC Athlon XP 2800+Mhz, Protect= ', 0.150:15:9,'  Sec');
dT:=Time;
c:=0.0;
For k:=1 to itnum do begin
For j:=1 to 33 do begin
For i:=1 to 12345 do begin
c:=c +Ln(0.12*(i+j+k)) +sqrt(0.19*(i+j+k)) +exp(Ln(0.26*(i+j+k))) +sin((i+j+k)*0.34) +cos((i+j+k)*0.77);
end;
end;
end;
dT:=Time-dT;
WriteLn('Time for this PC            = ',dT/itnum:15:9,'  Sec');
Repeat Until KeyPressed;
end.
###############          Test of PC ,DOS    ###############
...
Time for this PC            =     0.331333333  Sec###############          Test of PC ,DOS    ###############
...
Time for this PC            =     0.318666667  Sec
Сначала порадовался потом позапускав несколько раз и получив очень(!!!) разные результаты понял, что тест не объективен для многозадачных систем.
Вы бы asm-код сравнили, что ли... Благо, можно попросить компилятор его сохранить
For j:=1 to 10000 do begin
For i:=1 to 10000 do begin
c:=c +Ln((i+j)*0.001);
end;
end;
;[9] For j:=1 to 10000 do begin
   movl   $1,_J
   .balign 4,144
.L8:
; Register %eax allocated
; [10] For i:=1 to 10000 do begin
   movl   $1,_I
   .balign 4,144
.L13:
; Register %eax allocated
; [11] c:=c +Ln((i+j)*0.001);
   movl   _I,%eax
   addl   _J,%eax
   pushl   %eax
; Register %eax released
   fildl   (%esp)
; Register %edi allocated
   popl   %edi
; Register %edi released
   fldt   .L18             ; это коэффициент 0.001
   fmulp   %st,%st(1)
   fldln2
   fxch
   fyl2x
   faddl   _C
   fstpl   _C
; Register %eax allocated
   cmpl   $10000,_I
   jge   .L12
   incl   _I
   jmp   .L13
; Register %eax released
.L12:
; Register %eax allocated
   cmpl   $10000,_J
   jge   .L7
   incl   _J
   jmp   .L8
; [9] For j:=1 to 10000 do begin
   movl   $1,U_P$MYTEST_J
   decl   U_P$MYTEST_J
   .balign 4
.L8:
   incl   U_P$MYTEST_J
; [10] For i:=1 to 10000 do begin
   movl   $1,U_P$MYTEST_I
   decl   U_P$MYTEST_I
   .balign 4
.L11:
   incl   U_P$MYTEST_I
; Register %eax allocated
; [11] c:=c +Ln((i+j)*0.001);
   movl   U_P$MYTEST_I,%eax
   addl   U_P$MYTEST_J,%eax
; Temp -4,4 allocated
   movl   %eax,-4(%ebp)
; Register %eax released
   fildl   -4(%ebp)
; Temp -4,4 released
   fldt   _$PROGRAM$_L14     ; это коэффициент 0.001
   fmulp   %st,%st(1)
   fldln2
   fxch
   fyl2x
   faddl   U_P$MYTEST_C
   fstpl   U_P$MYTEST_C
   fwait                                            ; а вот он wait 
   cmpl   $10000,U_P$MYTEST_I
   jl   .L11
   cmpl   $10000,U_P$MYTEST_J
   jl   .L8
В древности (8088) команда привыполнении инструкции fwait сопроцессор ждал, когда основной процессор будет готов принять данные от сопроцессора (не уверен, так как воспроизвожу по памяти, а было это ой как давно) Я был уверен, что сейчас эта команда не используется.
 ведь в этом цикле вещественные вычисления идут подряд друг за другом и по большому счету не так уж и важно чтобы об ошибке стало известно прямо в срок. Эту проверку можно отложить вообще до конца цикла
 ведь в этом цикле вещественные вычисления идут подряд друг за другом и по большому счету не так уж и важно чтобы об ошибке стало известно прямо в срок. Эту проверку можно отложить вообще до конца цикла  . А еще лучше чтобы у компилятора была опция .  Я вот сейчас вспомнил что в более привычном для меня  MSVC были подобные опции, почитал msdn и точно - у них есть три режима компиляции вещественных вычислений - fast, precise (по умолчанию) и strict (вот там то компилятор и добавляет wait инструкции после каждого вещественного вычисления). Может у fpc и так есть что-то подобное? (я вообще-то паскалем занимаюсь очень эпизодически, только когда шеф попросит, так что не уверен). А если таких опций у fpc нет, то не плохо бы разработчикам их добавить. Я так думаю
. А еще лучше чтобы у компилятора была опция .  Я вот сейчас вспомнил что в более привычном для меня  MSVC были подобные опции, почитал msdn и точно - у них есть три режима компиляции вещественных вычислений - fast, precise (по умолчанию) и strict (вот там то компилятор и добавляет wait инструкции после каждого вещественного вычисления). Может у fpc и так есть что-то подобное? (я вообще-то паскалем занимаюсь очень эпизодически, только когда шеф попросит, так что не уверен). А если таких опций у fpc нет, то не плохо бы разработчикам их добавить. Я так думаю 

 . А виновата одна инструкция в коде вычисления  экспоненты. Впрочем эта инструкция тоже связана с обработкой исключений.
. А виновата одна инструкция в коде вычисления  экспоненты. Впрочем эта инструкция тоже связана с обработкой исключений. fn_exp proc
    push    ebp
    mov     ebp,esp
    fld     tbyte ptr [ebp+8]
    fldl2e
    fmulp   st(1),st
    fstcw    tmpcw1
    fstcw   tmpcw2
    and     tmpcw2,0F3FFh
    or       tmpcw2,400h
    fldcw   tmpcw2
    fld       st(0)
    frndint
    fldcw   tmpcw1
    fxch    st(1)
    fsub    st,st(1)
    f2xm1
    fld1
    faddp   st(1),st
    fscale
    fstp      st(1)
    jmp     loc_004027A5
loc_004027A5:
    leave
    ret     0Ch
fn_exp endp
fn_exp proc
    push    ebp
    mov     ebp,esp
    sub     esp,0Ch
    fld     tbyte ptr [ebp+8]
    fldl2e
    fmulp   st(1),st
    fstcw   tmpcw1
    fstcw   tmpcw2
    wait
    and     tmpcw2,0F3FFh
    or       tmpcw2,400h
    fldcw   tmpcw2
    fld     st(0)
    frndint
    fldcw   tmpcw1
    fxch    st(1)
    fsub    st,st(1)
    f2xm1
    fld1
    faddp   st(1),st
    fscale
    fstp    st(1)
    fclex
    jmp     loc_004027A5
loc_004027A5:
    leave
    ret     0Ch
fn_exp endp
Вернуться в Free Pascal Compiler
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1