Forth и другие саморасширяющиеся системы программирования Locations of visitors to this page
Текущее время: Пт мар 29, 2024 01:14

...
Google Search
Forth-FAQ Spy Grafic

Часовой пояс: UTC + 3 часа [ Летнее время ]




Начать новую тему Ответить на тему  [ Сообщений: 29 ]  На страницу 1, 2  След.
Автор Сообщение
 Заголовок сообщения: Глазковая оптимизация в Форте
СообщениеДобавлено: Вт июл 24, 2018 00:22 
Не в сети

Зарегистрирован: Чт янв 07, 2016 19:14
Сообщения: 1288
Благодарил (а): 3 раз.
Поблагодарили: 18 раз.
Оптимизатор работает как библиотека.
На данный момент при подключении сего творения (~er\opt\optimaizer.f) в контексте появится врем. словарь, в котором и содержатся обработчики оптимизаций.

Что сейчас есть:
Замена арифметических и пр. операций на итоговое значение.
К примеру вместо последовательности 10 2 * 5 + в коде сразу будет 25
Как это ни странно, но оптимизатор Новы тут несколько предсказуемей СПФа (вбейте в последнем : TEST 200 10 / ; и посмотрите дизассемблером)

Замена операций со стеком возвратов, пользовательскими переменными...
Замена операций со стеком данных. Внезапно, их всего две, да и то сделаны под нужды самого оптимизатора.

Замена условий IF и WHILE
Оптимизировал только более-менее часто встречающиеся варианты в своём коде. Вариантов на самом деле уйма.

И немного мелочи.
Тестовая компиляция выявила уменьшение объёма откомпилированных библиотек где-то на 2 кб. (без оптимизатора 14 кб).

_________________
Цель: сделать 64-битную Нову под Винду


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Глазковая оптимизация в Форте
СообщениеДобавлено: Вт авг 21, 2018 22:47 
Не в сети
Аватара пользователя

Зарегистрирован: Чт июл 20, 2006 11:31
Сообщения: 2168
Откуда: Екб
Благодарил (а): 0 раз.
Поблагодарили: 41 раз.
Рассмотрим варианты реализации в коде конкатенации строк для SPF и VFX,
в которых как раз используется глазковая оптимизация.
Код:
\ SPF
: s+(spf) ( a1 u1 a2 u2 -- a u )
  >R OVER R@ + ALLOCATE THROW
  DUP >R -ROT >R DUP >R MOVE
  R> R> R> ROT 2DUP + -ROT R@
  -ROT >R >R MOVE R> R> R> +
;
: s+(spfl) { a1 u1 a2 u2 \ a -- a u }
u1 u2 + ALLOCATE THROW TO a
a1 a u1 MOVE a2 a u1 + u2 MOVE a u1 u2 +
;

SEE s+(spf)
SEE s+(spfl)

CODE s+(spf)
5DA2A3 50               PUSH    EAX
5DA2A4 8B4504           MOV     EAX , 4 [EBP]
5DA2A7 030424           ADD     EAX , [ESP]
5DA2AA E8EDACF7FF       CALL    554F9C  ( ALLOCATE )
5DA2AF E800AEF7FF       CALL    5550B4  ( THROW )
5DA2B4 50               PUSH    EAX
5DA2B5 8B5504           MOV     EDX , 4 [EBP]
5DA2B8 894504           MOV     4 [EBP] , EAX
5DA2BB 8B4500           MOV     EAX , 0 [EBP]
5DA2BE 895500           MOV     0 [EBP] , EDX
5DA2C1 50               PUSH    EAX
5DA2C2 8B4500           MOV     EAX , 0 [EBP]
5DA2C5 50               PUSH    EAX
5DA2C6 8D6D04           LEA     EBP , 4 [EBP]
5DA2C9 E8B69AF7FF       CALL    553D84  ( MOVE )
5DA2CE 8945FC           MOV     FC [EBP] , EAX
5DA2D1 58               POP     EAX
5DA2D2 59               POP     ECX
5DA2D3 8BD1             MOV     EDX , ECX
5DA2D5 59               POP     ECX
5DA2D6 894DF4           MOV     F4 [EBP] , ECX
5DA2D9 8955F8           MOV     F8 [EBP] , EDX
5DA2DC 8BD1             MOV     EDX , ECX
5DA2DE 8945F0           MOV     F0 [EBP] , EAX
5DA2E1 8D0402           LEA     EAX , [EDX] [EAX]
5DA2E4 8B55F4           MOV     EDX , F4 [EBP]
5DA2E7 8945F4           MOV     F4 [EBP] , EAX
5DA2EA 8B45F0           MOV     EAX , F0 [EBP]
5DA2ED 8955F0           MOV     F0 [EBP] , EDX
5DA2F0 8B0C24           MOV     ECX , [ESP]
5DA2F3 8B55F0           MOV     EDX , F0 [EBP]
5DA2F6 894DF0           MOV     F0 [EBP] , ECX
5DA2F9 8955EC           MOV     EC [EBP] , EDX
5DA2FC 50               PUSH    EAX
5DA2FD 8B45EC           MOV     EAX , EC [EBP]
5DA300 50               PUSH    EAX
5DA301 8B45F0           MOV     EAX , F0 [EBP]
5DA304 8D6DF4           LEA     EBP , F4 [EBP]
5DA307 E8789AF7FF       CALL    553D84  ( MOVE )
5DA30C 8945FC           MOV     FC [EBP] , EAX
5DA30F 58               POP     EAX
5DA310 8945F8           MOV     F8 [EBP] , EAX
5DA313 58               POP     EAX
5DA314 59               POP     ECX
5DA315 8D0408           LEA     EAX , [EAX] [ECX]
5DA318 8D6DF8           LEA     EBP , F8 [EBP]
5DA31B C3               RET     NEAR
END-CODE
( 121 bytes, 47 instructions )

CODE s+(spfl)
5DA333 8945FC           MOV     FC [EBP] , EAX
5DA336 B810000000       MOV     EAX , # 10
5DA33B 8D6DFC           LEA     EBP , FC [EBP]
5DA33E E8A58DF7FF       CALL    5530E8  ( DRMOVE )
5DA343 8945FC           MOV     FC [EBP] , EAX
5DA346 B801000000       MOV     EAX , # 1
5DA34B 8D6DFC           LEA     EBP , FC [EBP]
5DA34E E8D18EF7FF       CALL    553224  ( (RALLOT) )
5DA353 6814000000       PUSH    , # 14
5DA358 686C325500       PUSH    , # 55326C
5DA35D 8945FC           MOV     FC [EBP] , EAX
5DA360 8B442414         MOV     EAX , 14 [ESP]
5DA364 0344240C         ADD     EAX , C [ESP]
5DA368 8D6DFC           LEA     EBP , FC [EBP]
5DA36B E82CACF7FF       CALL    554F9C  ( ALLOCATE )
5DA370 E83FADF7FF       CALL    5550B4  ( THROW )
5DA375 89442408         MOV     8 [ESP] , EAX
5DA379 8B442418         MOV     EAX , 18 [ESP]
5DA37D 8945FC           MOV     FC [EBP] , EAX
5DA380 8B442408         MOV     EAX , 8 [ESP]
5DA384 8945F8           MOV     F8 [EBP] , EAX
5DA387 8B442414         MOV     EAX , 14 [ESP]
5DA38B 8D6DF8           LEA     EBP , F8 [EBP]
5DA38E E8F199F7FF       CALL    553D84  ( MOVE )
5DA393 8945FC           MOV     FC [EBP] , EAX
5DA396 8B442410         MOV     EAX , 10 [ESP]
5DA39A 8945F8           MOV     F8 [EBP] , EAX
5DA39D 8B442408         MOV     EAX , 8 [ESP]
5DA3A1 03442414         ADD     EAX , 14 [ESP]
5DA3A5 8945F4           MOV     F4 [EBP] , EAX
5DA3A8 8B44240C         MOV     EAX , C [ESP]
5DA3AC 8D6DF4           LEA     EBP , F4 [EBP]
5DA3AF E8D099F7FF       CALL    553D84  ( MOVE )
5DA3B4 8945FC           MOV     FC [EBP] , EAX
5DA3B7 8B442408         MOV     EAX , 8 [ESP]
5DA3BB 8945F8           MOV     F8 [EBP] , EAX
5DA3BE 8B442414         MOV     EAX , 14 [ESP]
5DA3C2 0344240C         ADD     EAX , C [ESP]
5DA3C6 8D6DF8           LEA     EBP , F8 [EBP]
5DA3C9 C3               RET     NEAR
END-CODE
( 151 bytes, 40 instructions )


\ VFX
: s+(vfx) ( a1 u1 a2 u2 -- a u )
  >R OVER R@ + ALLOCATE THROW
  DUP >R -ROT >R DUP >R MOVE
  R> R> R> ROT 2DUP + -ROT R@
  -ROT >R >R MOVE R> R> R> +
;
: s+(vfxl) {: a1 u1 a2 u2 | a  -- a u :}
u1 u2 + ALLOCATE THROW TO a
a1 a u1 MOVE a2 a u1 + u2 MOVE a u1 u2 +

SEE s+(vfx)
SEE s+(vfxl)

s+(vfx)
( 004D45D0    53 )                    PUSH      EBX
( 004D45D1    8B1C24 )                MOV       EBX, [ESP]
( 004D45D4    035D04 )                ADD       EBX, [EBP+04]
( 004D45D7    FF1591604100 )          CALL      [00416091]      ALLOCATE
( 004D45DD    E82AECF3FF )            CALL      0041320C        THROW
( 004D45E2    53 )                    PUSH      EBX
( 004D45E3    FF7500 )                PUSH      [EBP]
( 004D45E6    8B5504 )                MOV       EDX, [EBP+04]
( 004D45E9    52 )                    PUSH      EDX
( 004D45EA    895D04 )                MOV       [EBP+04], EBX
( 004D45ED    8BDA )                  MOV       EBX, EDX
( 004D45EF    8D6D04 )                LEA       EBP, [EBP+04]
( 004D45F2    E88902F3FF )            CALL      00404880        MOVE
( 004D45F7    5A )                    POP       EDX
( 004D45F8    59 )                    POP       ECX
( 004D45F9    58 )                    POP       EAX
( 004D45FA    8D6DEC )                LEA       EBP, [EBP+-14]
( 004D45FD    894500 )                MOV       [EBP], EAX
( 004D4600    895504 )                MOV       [EBP+04], EDX
( 004D4603    894508 )                MOV       [EBP+08], EAX
( 004D4606    894D0C )                MOV       [EBP+0C], ECX
( 004D4609    895D10 )                MOV       [EBP+10], EBX
( 004D460C    8BDA )                  MOV       EBX, EDX
( 004D460E    035D00 )                ADD       EBX, [EBP]
( 004D4611    8B1424 )                MOV       EDX, [ESP]
( 004D4614    FF7504 )                PUSH      [EBP+04]
( 004D4617    FF7508 )                PUSH      [EBP+08]
( 004D461A    895D08 )                MOV       [EBP+08], EBX
( 004D461D    8BDA )                  MOV       EBX, EDX
( 004D461F    8D6D08 )                LEA       EBP, [EBP+08]
( 004D4622    E85902F3FF )            CALL      00404880        MOVE
( 004D4627    5A )                    POP       EDX
( 004D4628    59 )                    POP       ECX
( 004D4629    58 )                    POP       EAX
( 004D462A    03C1 )                  ADD       EAX, ECX
( 004D462C    8D6DF8 )                LEA       EBP, [EBP+-08]
( 004D462F    895500 )                MOV       [EBP], EDX
( 004D4632    895D04 )                MOV       [EBP+04], EBX
( 004D4635    8BD8 )                  MOV       EBX, EAX
( 004D4637    C3 )                    NEXT,
( 104 bytes, 40 instructions )

SEE s+(vfxl)
s+(vfxl)
( 004D46A0    8BD4 )                  MOV       EDX, ESP
( 004D46A2    FF7508 )                PUSH      [EBP+08]
( 004D46A5    FF7504 )                PUSH      [EBP+04]
( 004D46A8    FF7500 )                PUSH      [EBP]
( 004D46AB    53 )                    PUSH      EBX
( 004D46AC    52 )                    PUSH      EDX
( 004D46AD    57 )                    PUSH      EDI
( 004D46AE    8BFC )                  MOV       EDI, ESP
( 004D46B0    81EC04000000 )          SUB       ESP, 00000004
( 004D46B6    8B5D0C )                MOV       EBX, [EBP+0C]
( 004D46B9    8D6D10 )                LEA       EBP, [EBP+10]
( 004D46BC    8B5708 )                MOV       EDX, [EDI+08]
( 004D46BF    035710 )                ADD       EDX, [EDI+10]
( 004D46C2    8D6DFC )                LEA       EBP, [EBP+-04]
( 004D46C5    895D00 )                MOV       [EBP], EBX
( 004D46C8    8BDA )                  MOV       EBX, EDX
( 004D46CA    FF1591604100 )          CALL      [00416091]      ALLOCATE
( 004D46D0    E837EBF3FF )            CALL      0041320C        THROW
( 004D46D5    895FFC )                MOV       [EDI+-04], EBX
( 004D46D8    8D6DF8 )                LEA       EBP, [EBP+-08]
( 004D46DB    8B5F10 )                MOV       EBX, [EDI+10]
( 004D46DE    8B57FC )                MOV       EDX, [EDI+-04]
( 004D46E1    895500 )                MOV       [EBP], EDX
( 004D46E4    8B5714 )                MOV       EDX, [EDI+14]
( 004D46E7    895504 )                MOV       [EBP+04], EDX
( 004D46EA    E89101F3FF )            CALL      00404880        MOVE
( 004D46EF    8B5710 )                MOV       EDX, [EDI+10]
( 004D46F2    0357FC )                ADD       EDX, [EDI+-04]
( 004D46F5    8D6DF4 )                LEA       EBP, [EBP+-0C]
( 004D46F8    895500 )                MOV       [EBP], EDX
( 004D46FB    8B570C )                MOV       EDX, [EDI+0C]
( 004D46FE    895504 )                MOV       [EBP+04], EDX
( 004D4701    895D08 )                MOV       [EBP+08], EBX
( 004D4704    8B5F08 )                MOV       EBX, [EDI+08]
( 004D4707    E87401F3FF )            CALL      00404880        MOVE
( 004D470C    8B5708 )                MOV       EDX, [EDI+08]
( 004D470F    035710 )                ADD       EDX, [EDI+10]
( 004D4712    8D6DF8 )                LEA       EBP, [EBP+-08]
( 004D4715    8B4FFC )                MOV       ECX, [EDI+-04]
( 004D4718    894D00 )                MOV       [EBP], ECX
( 004D471B    895D04 )                MOV       [EBP+04], EBX
( 004D471E    8BDA )                  MOV       EBX, EDX
( 004D4720    8B6704 )                MOV       ESP, [EDI+04]
( 004D4723    8B3F )                  MOV       EDI, 0 [EDI]
( 004D4725    C3 )                    NEXT,
( 134 bytes, 45 instructions )
ok

Теперь напишем это по другому ( в SPF )
Код:
: s+(spfsa) \ a1 u1 a2 u2 -- a u
DUP $ 8 A+@P ALLOCATE THROW
5$54354152 $ 0x14 @P+A $ 0xC @P+A MOVE MOVE
;

SEE s+(spfsa)
CODE s+(spfsa)
5DA3E3 8945FC           MOV     FC [EBP] , EAX
5DA3E6 8D6DFC           LEA     EBP , FC [EBP]
5DA3E9 034508           ADD     EAX , 8 [EBP]
5DA3EC E8ABABF7FF       CALL    554F9C  ( ALLOCATE )
5DA3F1 E8BEACF7FF       CALL    5550B4  ( THROW )
5DA3F6 8B5D0C           MOV     EBX , C [EBP]
5DA3F9 8B7500           MOV     ESI , 0 [EBP]
5DA3FC 89450C           MOV     C [EBP] , EAX
5DA3FF 894500           MOV     0 [EBP] , EAX
5DA402 8945F4           MOV     F4 [EBP] , EAX
5DA405 8B4508           MOV     EAX , 8 [EBP]
5DA408 897508           MOV     8 [EBP] , ESI
5DA40B 8975FC           MOV     FC [EBP] , ESI
5DA40E 895DF8           MOV     F8 [EBP] , EBX
5DA411 8D6DF4           LEA     EBP , F4 [EBP]
5DA414 014500           ADD     0 [EBP] , EAX
5DA417 014500           ADD     0 [EBP] , EAX
5DA41A E86599F7FF       CALL    553D84  ( MOVE )
5DA41F E86099F7FF       CALL    553D84  ( MOVE )
5DA424 C3               RET     NEAR
END-CODE
( 66 bytes, 20 instructions )

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

_________________
С уважением, chess


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Глазковая оптимизация в Форте
СообщениеДобавлено: Ср авг 22, 2018 03:44 
Не в сети

Зарегистрирован: Пн янв 07, 2013 22:40
Сообщения: 2141
Благодарил (а): 8 раз.
Поблагодарили: 74 раз.
Ещё вариант работы со стеком. (возможно ещё где то можно ужаться) :)
Код:
: s+  \ a1 u1 a2 u2  -- a u
DUP 3 PICK +  DUP >R  ALLOCATE THROW  DUP >R
3 PICK + SWAP MOVE   R@ SWAP MOVE   R>  R>
;

SEE s+ (spf4)
Код:
5729DF 8945FC           MOV     FC [EBP] , EAX
5729E2 034504           ADD     EAX , 4 [EBP]
5729E5 50               PUSH    EAX
5729E6 8D6DFC           LEA     EBP , FC [EBP]
5729E9 E8AE25FEFF       CALL    554F9C  ( ALLOCATE )
5729EE E8C126FEFF       CALL    5550B4  ( THROW )
5729F3 50               PUSH    EAX
5729F4 034508           ADD     EAX , 8 [EBP]
5729F7 8B5500           MOV     EDX , 0 [EBP]
5729FA 894500           MOV     0 [EBP] , EAX
5729FD 8BC2             MOV     EAX , EDX
5729FF E88013FEFF       CALL    553D84  ( MOVE )
572A04 8BD0             MOV     EDX , EAX
572A06 8B0424           MOV     EAX , [ESP]
572A09 8945FC           MOV     FC [EBP] , EAX
572A0C 8BC2             MOV     EAX , EDX
572A0E 8D6DFC           LEA     EBP , FC [EBP]
572A11 E86E13FEFF       CALL    553D84  ( MOVE )
572A16 8945FC           MOV     FC [EBP] , EAX
572A19 58               POP     EAX
572A1A 8945F8           MOV     F8 [EBP] , EAX
572A1D 58               POP     EAX
572A1E 8D6DF8           LEA     EBP , F8 [EBP]
572A21 C3               RET     NEAR
END-CODE 
( 68 bytes, 24 instructions )

see s+ (vfx)
Код:
( 004D4620    8BD3 )                  MOV       EDX, EBX
( 004D4622    035D04 )                ADD       EBX, [EBP+04]
( 004D4625    53 )                    PUSH      EBX
( 004D4626    8D6DFC )                LEA       EBP, [EBP+-04]
( 004D4629    895500 )                MOV       [EBP], EDX
( 004D462C    FF1591604100 )          CALL      [00416091]      ALLOCATE
( 004D4632    E8D5EBF3FF )            CALL      0041320C        THROW
( 004D4637    53 )                    PUSH      EBX
( 004D4638    035D08 )                ADD       EBX, [EBP+08]
( 004D463B    8BD3 )                  MOV       EDX, EBX
( 004D463D    8B5D00 )                MOV       EBX, [EBP]
( 004D4640    895500 )                MOV       [EBP], EDX
( 004D4643    E83802F3FF )            CALL      00404880        MOVE
( 004D4648    8B1424 )                MOV       EDX, [ESP]
( 004D464B    8D6DFC )                LEA       EBP, [EBP+-04]
( 004D464E    895500 )                MOV       [EBP], EDX
( 004D4651    E82A02F3FF )            CALL      00404880        MOVE
( 004D4656    5A )                    POP       EDX
( 004D4657    59 )                    POP       ECX
( 004D4658    8D6DF8 )                LEA       EBP, [EBP+-08]
( 004D465B    895500 )                MOV       [EBP], EDX
( 004D465E    895D04 )                MOV       [EBP+04], EBX
( 004D4661    8BD9 )                  MOV       EBX, ECX
( 004D4663    C3 )                    NEXT,
( 68 bytes, 24 instructions )


P.S. Но, больше интересен замер скорости разных этих вариантов.


Последний раз редактировалось KPG Ср авг 22, 2018 12:04, всего редактировалось 2 раз(а).

Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Глазковая оптимизация в Форте
СообщениеДобавлено: Ср авг 22, 2018 09:39 
Не в сети

Зарегистрирован: Чт янв 07, 2016 19:14
Сообщения: 1288
Благодарил (а): 3 раз.
Поблагодарили: 18 раз.
Ну Нова так не смогёт :)
Девочка ещё не научилась.
К тому же в ваших примерах достаточно стекомаханий.
Максимум, что Нова сможет оптимизировать, так это связку DUP >R , да и то не уверен прописывал ли такой сценарий.

Мой вариант кода:
Код:
: S+
4 N>R
1 RPICK 3 RPICK + DUP CELL+ ALLOCATE THROW      \ CELL+ для нуля в конце
4 RPICK OVER 3 RPICK MOVE
2 RPICK OVER 3 RPICK + 1 RPICK MOVE
SWAP
5 CELLS RP@ + RP!               \ оптимизируется в одну инструкцию
;


Мне кажется слова такого рода не самый лучший пример для работы оптимизатора
В любом случае вызовы ALLOCATE MOVE THROW никто не отменял. А жрут-то они, особенно первый представитель ряда

_________________
Цель: сделать 64-битную Нову под Винду


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Глазковая оптимизация в Форте
СообщениеДобавлено: Ср авг 22, 2018 21:35 
Не в сети
Аватара пользователя

Зарегистрирован: Чт июл 20, 2006 11:31
Сообщения: 2168
Откуда: Екб
Благодарил (а): 0 раз.
Поблагодарили: 41 раз.
KPG писал(а):
Ещё вариант работы со стеком. (возможно ещё где то можно ужаться)

Эквилибр на стеке? Как-то не хочется на это тратить время.
Я, первое, что приходило в голову, то и писал на plain форте для реализации s+.
А насчет оптимизации, то то, что я предложил можно использовать и в "ручном" режиме:

Определение групп слов типа 'M+N', 'M-N', 'MorN', 'MandN', 'MxorN', M=N,
где M и N номера ячеек стека (Mmax = 9, Nmax = 9)
0 - это вершина(в регистре EAX), 1 - это ячейка под вершиной и тд
результат операции помещается в ячейку с номером M (всего около 600 вариантов от 0+0 до 9=9)

Код:
: eax+eax  0xC003 W,    ;
: eax+@ebp 0x4503 W, C, ;
: @ebp+eax 0x4501 W, C, ;
: ebx=@ebp 0x5D8B W, C, ;
: @ebp+ebx 0x5D01 W, C, ;
: eax-@ebp 0x452B W, C, ;
: @ebp-eax 0x4529 W, C, ;
: @ebp-ebx 0x5D29 W, C, ;
: eax|@ebp 0x450B W, C, ;
: @ebp|eax 0x4509 W, C, ;
: @ebp|ebx 0x5D09 W, C, ;
: eax&@ebp 0x4523 W, C, ;
: @ebp&eax 0x4521 W, C, ;
: @ebp&ebx 0x5D21 W, C, ;
: eax^eax  0xC033 W,    ;
: eax^@ebp 0x4533 W, C, ;
: @ebp^eax 0x4531 W, C, ;
: @ebp^ebx 0x5D31 W, C, ;
: eax=@ebp 0x458B W, C, ;
: @ebp=eax 0x4589 W, C, ;
: @ebp=ebx 0x5D89 W, C, ;

: NOTFOUND { a u \ p1 p2 op -- }
  a C@ TO p1 a 1+ C@ TO op a 2+ C@ TO p2
  u 3 <> p1 '0' ':' WITHIN p2 '0' ':' WITHIN OR 0= OR
  op '+' = op '-' = OR op '|' = OR op '&' = OR op '^' = OR op '=' = OR 0=  OR
  IF a u NOTFOUND EXIT THEN
  p1 '0' - 1- 4 * TO p1 p2 '0' - 1- 4 * TO p2
  p1 0< p2 0< AND op '+' = AND    IF eax+eax     EXIT THEN
  p1 0< p2 0< 0= AND op '+' = AND IF p2 eax+@ebp EXIT THEN
  p1 0< 0= p2 0< AND op '+' = AND IF p1 @ebp+eax EXIT THEN
  p1 0< 0= p2 0< 0= AND op '+' = AND IF p2 ebx=@ebp p1 @ebp+ebx EXIT THEN
  p1 0< p2 0< 0= AND op '-' = AND IF p2 eax-@ebp EXIT THEN
  p1 0< 0= p2 0< AND op '-' = AND IF p1 @ebp-eax EXIT THEN
  p1 0< 0= p2 0< 0= AND op '-' = AND IF p2 ebx=@ebp p1 @ebp-ebx EXIT THEN
  p1 0< p2 0< 0= AND op '|' = AND IF p2 eax|@ebp EXIT THEN
  p1 0< 0= p2 0< AND op '|' = AND IF p1 @ebp|eax EXIT THEN
  p1 0< 0= p2 0< 0= AND op '|' = AND IF p2 ebx=@ebp p1 @ebp|ebx EXIT THEN
  p1 0< p2 0< 0= AND op '&' = AND IF p2 eax&@ebp EXIT THEN
  p1 0< 0= p2 0< AND op '&' = AND IF p1 @ebp&eax EXIT THEN
  p1 0< 0= p2 0< 0= AND op '&' = AND IF p2 ebx=@ebp p1 @ebp&ebx EXIT THEN
  p1 0< p2 0< AND op '^' = AND    IF eax^eax     EXIT THEN
  p1 0< p2 0< 0= AND op '^' = AND IF p2 eax^@ebp EXIT THEN
  p1 0< 0= p2 0< AND op '^' = AND IF p1 @ebp^eax EXIT THEN
  p1 0< 0= p2 0< 0= AND op '^' = AND IF p2 ebx=@ebp p1 @ebp^ebx EXIT THEN
  p1 0< p2 0< 0= AND op '=' = AND IF p2 eax=@ebp EXIT THEN
  p1 0< 0= p2 0< AND op '=' = AND IF p1 @ebp=eax EXIT THEN
  p1 0< 0= p2 0< 0= AND op '=' = AND IF p2 ebx=@ebp p1 @ebp=ebx EXIT THEN
;
\ и тогда для s+
            \ 3  2  1  0
: s+(spfsa) \ a1 u1 a2 u2 -- a u
DUP  0+3 ALLOCATE THROW
\ 76543210 - номера ячеек
5$54354152 6+0 4+0 MOVE MOVE
;

пс.
DUP-ами растягиваем стек, формируем набор параметров из уже существующих на стеке и тд...
Можно, если нужно, легко дополнить и другими операциями( *, /, MOD и тп и тд ).
Получается что-то типа стекового ассемблера. Непереносимо, но Форт-программы и так практически не переносятся, несмотря на наличие всяких стандартов.

_________________
С уважением, chess


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Глазковая оптимизация в Форте
СообщениеДобавлено: Ср авг 22, 2018 23:56 
Не в сети

Зарегистрирован: Пн янв 07, 2013 22:40
Сообщения: 2141
Благодарил (а): 8 раз.
Поблагодарили: 74 раз.
chess писал(а):
Эквилибр на стеке? Как-то не хочется на это тратить время.

Отнюдь. :) Правильное понимание механики возможностей стека.
И да, четыре входных параметров слова на стеке - это не типичный случай.
В этом варианте строки могут быть и со счётчиком.


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Глазковая оптимизация в Форте
СообщениеДобавлено: Чт авг 23, 2018 15:46 
Не в сети

Зарегистрирован: Чт янв 07, 2016 19:14
Сообщения: 1288
Благодарил (а): 3 раз.
Поблагодарили: 18 раз.
chess писал(а):
KPG писал(а):
Ещё вариант работы со стеком. (возможно ещё где то можно ужаться)

Эквилибр на стеке?
Получается что-то типа стекового ассемблера. Непереносимо, но Форт-программы и так практически не переносятся, несмотря на наличие всяких стандартов.


Хм, у меня есть похожий.
Только вместо безконечной череды IF THEN
Поиск ведётся в словаре.

И в чём проблема переносимости?
К примеру для новой архитектуры, моему варианту придётся всего лишь подключить другой форт-ассемблер и переписать алиасы

Если уж говорить о работе такого слова, как s+
то быстрее всего будет реализовать на асме, если уж очень критично

_________________
Цель: сделать 64-битную Нову под Винду


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Глазковая оптимизация в Форте
СообщениеДобавлено: Чт авг 30, 2018 09:52 
Не в сети
Аватара пользователя

Зарегистрирован: Чт июл 20, 2006 11:31
Сообщения: 2168
Откуда: Екб
Благодарил (а): 0 раз.
Поблагодарили: 41 раз.
Уменьшил объем писанины путем использования макросов, расширил количество групп слов
пересылками из ячейки в ячейку и обменом между ячейками, а также ввел группу по увеличению
глубины стека
Код:
\ инструкции
: a+a  0xC003 W,    ;
: a+@p 0x4503 W, C, ;
: @p+a 0x4501 W, C, ;
: b=@p 0x5D8B W, C, ;
: @p+b 0x5D01 W, C, ;
: a-@p 0x452B W, C, ;
: @p-a 0x4529 W, C, ;
: @p-b 0x5D29 W, C, ;
: a|@p 0x450B W, C, ;
: @p|a 0x4509 W, C, ;
: @p|b 0x5D09 W, C, ;
: a&@p 0x4523 W, C, ;
: @p&a 0x4521 W, C, ;
: @p&b 0x5D21 W, C, ;
: a^a  0xC033 W,    ;
: a^@p 0x4533 W, C, ;
: @p^a 0x4531 W, C, ;
: @p^b 0x5D31 W, C, ;
: a=@p 0x458B W, C, ;
: @p=a 0x4589 W, C, ;
: @p=b 0x5D89 W, C, ;
: b=a  0xD88B W,    ;
: a=b  0xC38B W,    ;
: d=@p 0x558B W, C, ;
: @p=d 0x5589 W, C, ;
: p+   0x6D8D W, C, ;

\ макросы
M: b00 op = p1 0< p2 0< AND AND IF ;
M: bp0 op = p1 0< 0= p2 0< AND AND IF ;
M: b0p op = p1 0< p2 0< 0= AND AND IF ;
M: bpp op = p1 0< 0= p2 0< 0= AND AND IF ;
M: end EXIT THEN ;

\ определение групп слов типа 'M+N', 'M-N', 'M|N', 'M&N', 'M^N',
\ M=N(пересылка из N в M), M~N(swap M N), M_0(увеличение глубины стека)
\ где M и N номера ячеек стека (Mmax = 9, Nmax = 9)
\ 0 - это вершина(в регистре EAX), 1 - это ячейка под вершиной и тд
\ результат операции помещается в ячейку с номером M (всего около 700 вариантов от 0+0 до 9~9)
: NOTFOUND { a u \ p1 p2 op -- }
  a C@ TO p1 a 1+ C@ TO op a 2+ C@ TO p2
  u 3 <> p1 '0' ':' WITHIN p2 '0' ':' WITHIN OR 0= OR
  op '_' = op '+' = OR op '-' = OR op '|' = OR op '&' = OR op '^' = OR op '=' = OR op '~' = OR 0=  OR
  IF a u NOTFOUND EXIT THEN
  p1 '0' - 1- 4 * TO p1 p2 '0' - 1- 4 * TO p2
  '+' b00 a+a end  '+' b0p p2 a+@p end  '+' bp0 p1 @p+a end  '+' bpp p2 b=@p p1 @p+b end
                   '-' b0p p2 a-@p end  '-' bp0 p1 @p-a end  '-' bpp p2 b=@p p1 @p-b end
                   '|' b0p p2 a|@p end  '|' bp0 p1 @p|a end  '|' bpp p2 b=@p p1 @p|b end
                   '&' b0p p2 a&@p end  '&' bp0 p1 @p&a end  '&' bpp p2 b=@p p1 @p&b end
  '^' b00 a^a end  '^' b0p p2 a^@p end  '^' bp0 p1 @p^a end  '^' bpp p2 b=@p p1 @p^b end
                   '=' b0p p2 a=@p end  '=' bp0 p1 @p=a end  '=' bpp p2 b=@p p1 @p=b end
  '~' b0p b=a p2 a=@p p2 @p=b end  '~' bp0 p1 b=@p p1 @p=a a=b end  '~' bpp p2 b=@p p1 d=@p p1 @p=b p2 @p=d end
  '_' bp0 p1 CELL+ NEGATE p+ end
;

PS.
Получил "побочный" результат на лексеме 1_0(увеличение глубины стека на 1 ячейку).
Код:
: tst 1_0 ; SEE tst
CODE tst
5DB217 8D6DFC           LEA     EBP , FC [EBP]
5DB21A C3               RET     NEAR
END-CODE
( 4 bytes, 2 instructions )

Ok
1 tst
Ok ( 1 1 )

1_0 работает как DUP, т.е. DUP
можно определить проще, а именно:
Код:
: DUP $ -4 Pa ;
или
Код:
CODE DUP
LEA     EBP , FC [EBP]
RET     NEAR
END-CODE

_________________
С уважением, chess


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Глазковая оптимизация в Форте
СообщениеДобавлено: Чт авг 30, 2018 16:37 
Не в сети

Зарегистрирован: Чт янв 07, 2016 19:14
Сообщения: 1288
Благодарил (а): 3 раз.
Поблагодарили: 18 раз.
DUP
Копирует верхний элемент стека, а не выделяет на нём память :) :P

Корректней
Код:
LEA EBP, [EBP-CELL]
MOV [EBP], EAX
RET


Или в моём варианте:
Код:
0/00

_________________
Цель: сделать 64-битную Нову под Винду


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Глазковая оптимизация в Форте
СообщениеДобавлено: Чт авг 30, 2018 21:14 
Не в сети
Аватара пользователя

Зарегистрирован: Чт июл 20, 2006 11:31
Сообщения: 2168
Откуда: Екб
Благодарил (а): 0 раз.
Поблагодарили: 41 раз.
Victor__v писал(а):
DUP
Копирует верхний элемент стека, а не выделяет на нём память

Точнее увеличивает глубину стека на одну ячейку памяти, которая становится новой верхней ячейкой стека.
В эту новую верхнюю ячейку копирует данные из предыдущей верхней ячейки стека(это когда стек весь в памяти).
В SPF верхняя ячейка стека находится в регистре EAX, поэтому его содержимое копируется в новую добавленную ячейку стека.
Если просто добавить ячейку в стек, передвинув указатель на эту добавленную ячейку без копирования в нее содержимого
EAX, то в этой ячейке стека должно быть неопределенное значение, а на практике это не так. Мне это непонятно. :(

_________________
С уважением, chess


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Глазковая оптимизация в Форте
СообщениеДобавлено: Пт авг 31, 2018 04:06 
Не в сети

Зарегистрирован: Чт янв 07, 2016 19:14
Сообщения: 1288
Благодарил (а): 3 раз.
Поблагодарили: 18 раз.
Скомпилируй пару таких инструкций подряд в слове и вызови его.
И просветление не за горами :)

_________________
Цель: сделать 64-битную Нову под Винду


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Глазковая оптимизация в Форте
СообщениеДобавлено: Пт авг 31, 2018 08:50 
Не в сети
Аватара пользователя

Зарегистрирован: Чт июл 20, 2006 11:31
Сообщения: 2168
Откуда: Екб
Благодарил (а): 0 раз.
Поблагодарили: 41 раз.
Victor__v писал(а):
Скомпилируй пару таких инструкций подряд в слове и вызови его.
И просветление не за горами

Меня интересует вариант не только с компиляцией, но и с интерпретацией, хотя и с компиляцией
непонятки остаются(по вашему предложению только одна ячейка остается в неопределенном состоянии, а должно
быть две). Подозреваю, что это связано с работой встроенного оптимизатора, но лобовой вариант его отключения
(типа DIS-OPT и 0 TO MM_SIZE) ничего не дает. А при интерпретации что DUP что dup дают один результат:

Код:
: dup $ -4 Pa ;  SEE dup


CODE dup
5DA29F 8D6DFC LEA EBP , FC [EBP]
5DA2A2 C3 RET NEAR
END-CODE
( 4 bytes, 2 instructions )

Код:
1 dup dup

Ok ( 1 1 1 )

_________________
С уважением, chess


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Глазковая оптимизация в Форте
СообщениеДобавлено: Пт авг 31, 2018 17:47 
Не в сети

Зарегистрирован: Чт янв 07, 2016 19:14
Сообщения: 1288
Благодарил (а): 3 раз.
Поблагодарили: 18 раз.
Думаю, нет смысла обсуждать эту скрытую фичу.
Лучше уж обсудить как лучше делать разбор кода постфактум (для форта это наиболее надёжно).
Хотя это уже не глазковая оптимизация, так как можно к коду применять параметры (скорость, размер и их комбинации)

_________________
Цель: сделать 64-битную Нову под Винду


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Глазковая оптимизация в Форте
СообщениеДобавлено: Вс фев 24, 2019 21:53 
Не в сети

Зарегистрирован: Чт янв 07, 2016 19:14
Сообщения: 1288
Благодарил (а): 3 раз.
Поблагодарили: 18 раз.
Оптимизация в Nova-forth
Зачем она нужна?
Повышение ТТХ Новы и приложений написанных на ней (размер, скорость и пр.).

Как сейчас обстоят дела?
При целевой компиляции размер Новы ужимается примерно на 2 кб. Эта работа делается препроцессором написанным на форте. Простота заданий подстановок делает препроцессор идеальным вариантом для сборки стабильного форт-кода (т. е. без полиморфизма).

Но для оптимизации кода для приложений он может не подойти из-за того же полиморфизма.

Поэтому в Нове по умолчанию (прописано в INI-файле) используется простейший оптимизатор нативного форт-кода.
Что примечательно, ассемблер в этом случае не участвует вообще никак. Всё достигается самими средствами форта. Что повышает пригодность оптимизатора к разным разрядностям и архитектурам. По крайней мере, портировать будет достаточно просто.

Однако ограничения "использовать только форт" и "не использовать ассемблер" сказываются на списке правил оптимизации - их мало.
По этой причине использование такого оптимизатора даёт результат минимум эффекта при минимуме усилий.
Также в 6-м обновлении этот оптимизатор был несколько "усилен". Так в нём появились правила, которые "проверяют на вшивость" следующее слово. Но поскольку оптимизатор применяется на месте (где указан соответствующий контекст и состояние глоб. переменных), то такой закос под препроцессор не играет роли.

Моя скромная мечта написать нормальный оптимизатор с ассемблером в своё время наткнулась на необходимость дизассемблера, чтобы после компактификации кода по правилам убрать последние "косяки", программные "криворукости" и то, что в падлу вычленять фортом. Однако на данным момент "нормальный" оптимизатор заброшен. И работоспособность кода на выходе давно (полтора месяца, минимум) не тестировалась.

_________________
Цель: сделать 64-битную Нову под Винду


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Глазковая оптимизация в Форте
СообщениеДобавлено: Вс фев 24, 2019 23:02 
Не в сети
Administrator
Administrator
Аватара пользователя

Зарегистрирован: Вт май 02, 2006 22:48
Сообщения: 7960
Благодарил (а): 25 раз.
Поблагодарили: 144 раз.
Victor__v писал(а):
Повышение ТТХ Новы и приложений написанных на ней (размер, скорость и пр.).

А, в свою очередь, зачем нужно вот это?


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 29 ]  На страницу 1, 2  След.

Часовой пояс: UTC + 3 часа [ Летнее время ]


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 7


Вы не можете начинать темы
Вы можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
phpBB сборка от FladeX // Русская поддержка phpBB