[Fwd: Re: Optimisation]

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

[Fwd: Re: Optimisation]

Andrey Cherezov
Привет!
Кто у нас специалист по оптимизации? Берем эти патчи?

-------- Исходное сообщение --------
Тема: Re: Optimisation MOVE >NUMBER
Дата: Sat, 28 Mar 2009 21:04:30 +0300 (????)
От: Ivanov Arthur - lead.programmer [hidden email]

Можно вам предложить еще немного мелких оптимизаций к SP-Forth 4.x.
Если конечно Вы надете это полезным.

-------------------------------------------------------------------
                                COMPARE

COMPARE в SPF 4.20 записано так :

CODE COMPARE ( c-addr1 u1 c-addr2 u2 -- n ) \ 94 STRING
\ Сравнить строку, заданную c-addr1 u1, со строкой, заданной c-addr2 u2.
\ Строки сравниваются, начиная с заданных адресов, символ за символом, до длины 
\ наиболее короткой из строк или до нахождения различий. Если две строки 
\ идентичны, n ноль. Если две строки идентичны до длины наиболее короткой из 
\ строк, то n минус единица (-1), если u1 меньше u2, иначе единица (1).
\ Если две строки не идентичны до длины наиболее короткой из строк, то n минус 
\ единица (-1), если первый несовпадающий символ строки, заданной c-addr1 u1
\ имеет меньшее числовое значение, чем соответствующий символ в строке, 
\ заданной c-addr2 u2, и единица в противном случае.
      MOV EDX, EDI
      MOV EDI,   [EBP]
      MOV ECX, 4 [EBP]
      MOV ESI, 8 [EBP]
      LEA EBP, 0C [EBP]  \    ADD EBP, # 0C   ####
      CMP ECX, EAX
      PUSHFD
      JC  SHORT @@1
      MOV ECX, EAX
@@1:  JECXZ @@2
      CLD
      REPZ CMPS BYTE
      JZ  SHORT @@2
      POP EBX
      A;  B8 C, -1 DUP W, W, \  MOV EAX, # -1
      JC  SHORT @@3
      NEG EAX
      JMP SHORT @@3
@@2:  XOR EAX, EAX
      POPFD
      JZ  SHORT @@3
      A;  B8 C, -1 DUP W, W, \  MOV EAX, # -1
      JC  SHORT @@3
      NEG EAX
@@3:  MOV EDI, EDX
      RET
END-CODE

Забавно, но этот алгоритм очень сильно свертывается, если применить
вычурные команды LAHF и SAHF. Я посмотрел по справочнику, однако
они выполняются на P5 и P6 куда быстрее PUSHF и POPF.
Вот смотрите :

CODE COMPARE ( c-addr1 u1 c-addr2 u2 -- n ) \ 94 STRING
\ Сравнить строку, заданную c-addr1 u1, со строкой, заданной c-addr2 u2.
\ Строки сравниваются, начиная с заданных адресов, символ за символом, до длины 
\ наиболее короткой из строк или до нахождения различий. Если две строки 
\ идентичны, n ноль. Если две строки идентичны до длины наиболее короткой из 
\ строк, то n минус единица (-1), если u1 меньше u2, иначе единица (1).
\ Если две строки не идентичны до длины наиболее короткой из строк, то n минус 
\ единица (-1), если первый несовпадающий символ строки, заданной c-addr1 u1
\ имеет меньшее числовое значение, чем соответствующий символ в строке, 
\ заданной c-addr2 u2, и единица в противном случае.
      MOV ECX, 4 [EBP]
      MOV EDX, EDI
      MOV ESI, 8 [EBP]
      MOV EDI, 0 [EBP]
      LEA EBP, 0C [EBP]
      CMP ECX, EAX
      JC  SHORT @@1
      MOV ECX, EAX
@@1:  LAHF
      JECXZ @@2
      CLD
      REPZ CMPS BYTE
      JNZ  SHORT @@3
@@2:  SAHF
      MOV EAX, ECX
      JZ  SHORT @@4
@@3:  SBB EAX, EAX
      OR  EAX, # 1
@@4:  MOV EDI, EDX
      RET
END-CODE

-------------------------------------------------------------------
                                FM/MOD

Еще скромная оптимизация :

\ From: Serguei V. Jidkov [[hidden email]]

CODE FM/MOD ( d1 n1 -- n2 n3 ) \ 94
\ Разделить d1 на n1, получить частное n3 и остаток n2.
\ Входные и выходные аргументы знаковые.
\ Неоднозначная ситуация возникает, если n1 ноль, или частное вне
\ диапазона одинарных знаковых чисел.
        MOV ECX, EAX
        MOV EDX, 0 [EBP]
        MOV EBX, EDX
        MOV EAX, 4 [EBP]
        IDIV ECX
        TEST EDX, EDX            \ Остаток-то есть?
        JZ  SHORT @@1
        XOR EBX, ECX             \ А аргументы разного знака?
        JNS SHORT @@1
        DEC EAX
        ADD EDX, ECX
@@1:    LEA EBP, 4 [EBP]
        MOV 0 [EBP], EDX
        RET
END-CODE

Очень красиво, только в моем Форте записано на команду короче :

CODE FM/MOD ( d1 n1 -- n2 n3 ) \ 94
\ Разделить d1 на n1, получить частное n3 и остаток n2.
\ Входные и выходные аргументы знаковые.
\ Неоднозначная ситуация возникает, если n1 ноль, или частное вне
\ диапазона одинарных знаковых чисел.
        MOV EDX, 0 [EBP]
        MOV ECX, EAX
        MOV EAX, 4 [EBP]
        IDIV ECX
        TEST EDX, EDX            \ Остаток-то есть?
        JZ  SHORT @@1
        TEST EAX, EAX            \ А аргументы разного знака?
        JNS SHORT @@1
        ADD EDX, ECX
        DEC EAX
@@1:    LEA EBP, 4 [EBP]
        MOV 0 [EBP], EDX
        RET
END-CODE

-------------------------------------------------------------------
                            Относительно LEA

У вас часто LEA используется там, где достаточно одной INC reg и DEC reg.
В такой замене нет никакого смысла ибо INC reg и DEC reg выполняются
минимально возможное время на любом процессоре и в длину они короче.
А вот LEA даст AGI с предыдущей командой на Pentium и израсходуется
лишний такт. А у вас в коде TRAILING- и SEARCH AGI будет сто пудов.

Так-что лучше заменить
LEA EAX,  1 [EAX] на INC EAX    в слове    1+
LEA EAX, -1 [EAX] на DEC EAX    в слове    1-
LEA EDI, -1 [EDI] на DEC EDI    в слове    TRAILING-
LEA ECX, -1 [ECX] на DEC ECX    в слове    SEARCH
LEA EAX,  1 [EAX] на INC EAX    в слове    ASCIIZ>
LEA EAX, -1 [EAX] на DEC EAX    в слове    ASCIIZ>

-------------------------------------------------------------------
                            Всякие мелочи

Мне кажется, что вот так будет короче, красивше и не медленнее :

CODE 2*
     D1 C, E0 C, \ SHL EAX, # 1
     RET
END-CODE

CODE U2/        ( N1 -- N2 ) \ unsigned divide n1 by two
     D1 C, E8 C, \ SHR EAX, # 1
     RET
END-CODE

CODE ABS ( n -- u ) \ 94
\ u - абсолютная величина n.
    CDQ
    XOR     EAX, EDX
    SUB     EAX, EDX
    RET
END-CODE


P.P.S.
: CZMOVE ( a # z --) 2DUP + >R SWAP CMOVE R> 0 SWAP C! ;
лучше записать так
: CZMOVE ( a # z --) 2DUP + >R SWAP CMOVE 0 R> C! ;

------------------------------------------------------------------------------

_______________________________________________
Spf-dev mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spf-dev
Reply | Threaded
Open this post in threaded view
|

Re: [Fwd: Re: Optimisation]

ygrek-3
On Sat, 28 Mar 2009 21:53:38 +0200
Andrey Cherezov <[hidden email]> wrote:

> -------- Исходное сообщение --------
> Тема: Re: Optimisation MOVE >NUMBER
> Дата: Sat, 28 Mar 2009 21:04:30 +0300 (????)
> От: Ivanov Arthur - lead.programmer <[hidden email]>

> Забавно, но этот алгоритм очень сильно свертывается, если применить
> вычурные команды LAHF и SAHF. Я посмотрел по справочнику, однако
> они выполняются на P5 и P6 куда быстрее PUSHF и POPF.

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

Я не специалист по теории, а как на практике замерить остальное я даже не представляю.

--
 ~ygrek

------------------------------------------------------------------------------
OpenSolaris 2009.06 is a cutting edge operating system for enterprises
looking to deploy the next generation of Solaris that includes the latest
innovations from Sun and the OpenSource community. Download a copy and
enjoy capabilities such as Networking, Storage and Virtualization.
Go to: http://p.sf.net/sfu/opensolaris-get
_______________________________________________
Spf-dev mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spf-dev

bench.f (2K) Download Attachment
attachment1 (204 bytes) Download Attachment