Forth http://fforum.winglion.ru/ |
|
Глазковая оптимизация в Форте http://fforum.winglion.ru/viewtopic.php?f=58&t=3185 |
Страница 1 из 2 |
Автор: | Victor__v [ Вт июл 24, 2018 00:22 ] |
Заголовок сообщения: | Глазковая оптимизация в Форте |
Оптимизатор работает как библиотека. На данный момент при подключении сего творения (~er\opt\optimaizer.f) в контексте появится врем. словарь, в котором и содержатся обработчики оптимизаций. Что сейчас есть: Замена арифметических и пр. операций на итоговое значение. К примеру вместо последовательности 10 2 * 5 + в коде сразу будет 25 Как это ни странно, но оптимизатор Новы тут несколько предсказуемей СПФа (вбейте в последнем : TEST 200 10 / ; и посмотрите дизассемблером) Замена операций со стеком возвратов, пользовательскими переменными... Замена операций со стеком данных. Внезапно, их всего две, да и то сделаны под нужды самого оптимизатора. Замена условий IF и WHILE Оптимизировал только более-менее часто встречающиеся варианты в своём коде. Вариантов на самом деле уйма. И немного мелочи. Тестовая компиляция выявила уменьшение объёма откомпилированных библиотек где-то на 2 кб. (без оптимизатора 14 кб). |
Автор: | chess [ Вт авг 21, 2018 22:47 ] |
Заголовок сообщения: | Re: Глазковая оптимизация в Форте |
Рассмотрим варианты реализации в коде конкатенации строк для 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 ). Такой подход похоже будет попроще в реализации и эффективнее по результату, чем глазковая оптимизация. |
Автор: | KPG [ Ср авг 22, 2018 03:44 ] |
Заголовок сообщения: | Re: Глазковая оптимизация в Форте |
Ещё вариант работы со стеком. (возможно ещё где то можно ужаться) Код: : 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. Но, больше интересен замер скорости разных этих вариантов. |
Автор: | Victor__v [ Ср авг 22, 2018 09:39 ] |
Заголовок сообщения: | Re: Глазковая оптимизация в Форте |
Ну Нова так не смогёт Девочка ещё не научилась. К тому же в ваших примерах достаточно стекомаханий. Максимум, что Нова сможет оптимизировать, так это связку 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 никто не отменял. А жрут-то они, особенно первый представитель ряда |
Автор: | chess [ Ср авг 22, 2018 21:35 ] |
Заголовок сообщения: | Re: Глазковая оптимизация в Форте |
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 и тп и тд ). Получается что-то типа стекового ассемблера. Непереносимо, но Форт-программы и так практически не переносятся, несмотря на наличие всяких стандартов. |
Автор: | KPG [ Ср авг 22, 2018 23:56 ] |
Заголовок сообщения: | Re: Глазковая оптимизация в Форте |
chess писал(а): Эквилибр на стеке? Как-то не хочется на это тратить время. Отнюдь. Правильное понимание механики возможностей стека. И да, четыре входных параметров слова на стеке - это не типичный случай. В этом варианте строки могут быть и со счётчиком. |
Автор: | Victor__v [ Чт авг 23, 2018 15:46 ] |
Заголовок сообщения: | Re: Глазковая оптимизация в Форте |
chess писал(а): KPG писал(а): Ещё вариант работы со стеком. (возможно ещё где то можно ужаться) Эквилибр на стеке? Получается что-то типа стекового ассемблера. Непереносимо, но Форт-программы и так практически не переносятся, несмотря на наличие всяких стандартов. Хм, у меня есть похожий. Только вместо безконечной череды IF THEN Поиск ведётся в словаре. И в чём проблема переносимости? К примеру для новой архитектуры, моему варианту придётся всего лишь подключить другой форт-ассемблер и переписать алиасы Если уж говорить о работе такого слова, как s+ то быстрее всего будет реализовать на асме, если уж очень критично |
Автор: | chess [ Чт авг 30, 2018 09:52 ] |
Заголовок сообщения: | Re: Глазковая оптимизация в Форте |
Уменьшил объем писанины путем использования макросов, расширил количество групп слов пересылками из ячейки в ячейку и обменом между ячейками, а также ввел группу по увеличению глубины стека Код: \ инструкции : 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 |
Автор: | Victor__v [ Чт авг 30, 2018 16:37 ] |
Заголовок сообщения: | Re: Глазковая оптимизация в Форте |
DUP Копирует верхний элемент стека, а не выделяет на нём память Корректней Код: LEA EBP, [EBP-CELL] MOV [EBP], EAX RET Или в моём варианте: Код: 0/00
|
Автор: | chess [ Чт авг 30, 2018 21:14 ] |
Заголовок сообщения: | Re: Глазковая оптимизация в Форте |
Victor__v писал(а): DUP Копирует верхний элемент стека, а не выделяет на нём память Точнее увеличивает глубину стека на одну ячейку памяти, которая становится новой верхней ячейкой стека. В эту новую верхнюю ячейку копирует данные из предыдущей верхней ячейки стека(это когда стек весь в памяти). В SPF верхняя ячейка стека находится в регистре EAX, поэтому его содержимое копируется в новую добавленную ячейку стека. Если просто добавить ячейку в стек, передвинув указатель на эту добавленную ячейку без копирования в нее содержимого EAX, то в этой ячейке стека должно быть неопределенное значение, а на практике это не так. Мне это непонятно. |
Автор: | Victor__v [ Пт авг 31, 2018 04:06 ] |
Заголовок сообщения: | Re: Глазковая оптимизация в Форте |
Скомпилируй пару таких инструкций подряд в слове и вызови его. И просветление не за горами |
Автор: | chess [ Пт авг 31, 2018 08:50 ] |
Заголовок сообщения: | Re: Глазковая оптимизация в Форте |
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 ) |
Автор: | Victor__v [ Пт авг 31, 2018 17:47 ] |
Заголовок сообщения: | Re: Глазковая оптимизация в Форте |
Думаю, нет смысла обсуждать эту скрытую фичу. Лучше уж обсудить как лучше делать разбор кода постфактум (для форта это наиболее надёжно). Хотя это уже не глазковая оптимизация, так как можно к коду применять параметры (скорость, размер и их комбинации) |
Автор: | Victor__v [ Вс фев 24, 2019 21:53 ] |
Заголовок сообщения: | Re: Глазковая оптимизация в Форте |
Оптимизация в Nova-forth Зачем она нужна? Повышение ТТХ Новы и приложений написанных на ней (размер, скорость и пр.). Как сейчас обстоят дела? При целевой компиляции размер Новы ужимается примерно на 2 кб. Эта работа делается препроцессором написанным на форте. Простота заданий подстановок делает препроцессор идеальным вариантом для сборки стабильного форт-кода (т. е. без полиморфизма). Но для оптимизации кода для приложений он может не подойти из-за того же полиморфизма. Поэтому в Нове по умолчанию (прописано в INI-файле) используется простейший оптимизатор нативного форт-кода. Что примечательно, ассемблер в этом случае не участвует вообще никак. Всё достигается самими средствами форта. Что повышает пригодность оптимизатора к разным разрядностям и архитектурам. По крайней мере, портировать будет достаточно просто. Однако ограничения "использовать только форт" и "не использовать ассемблер" сказываются на списке правил оптимизации - их мало. По этой причине использование такого оптимизатора даёт результат минимум эффекта при минимуме усилий. Также в 6-м обновлении этот оптимизатор был несколько "усилен". Так в нём появились правила, которые "проверяют на вшивость" следующее слово. Но поскольку оптимизатор применяется на месте (где указан соответствующий контекст и состояние глоб. переменных), то такой закос под препроцессор не играет роли. Моя скромная мечта написать нормальный оптимизатор с ассемблером в своё время наткнулась на необходимость дизассемблера, чтобы после компактификации кода по правилам убрать последние "косяки", программные "криворукости" и то, что в падлу вычленять фортом. Однако на данным момент "нормальный" оптимизатор заброшен. И работоспособность кода на выходе давно (полтора месяца, минимум) не тестировалась. |
Автор: | Hishnik [ Вс фев 24, 2019 23:02 ] |
Заголовок сообщения: | Re: Глазковая оптимизация в Форте |
Victor__v писал(а): Повышение ТТХ Новы и приложений написанных на ней (размер, скорость и пр.). А, в свою очередь, зачем нужно вот это? |
Страница 1 из 2 | Часовой пояс: UTC + 3 часа [ Летнее время ] |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |