Автор |
Сообщение |
|
|
Заголовок сообщения: |
Re: Как сделать форт-процессор 2022 |
|
|
Выдалась свободная минутка, перепрогнал Dhrystone через свои процессоры, ибо мой компилятор Си-в-Форт чуточку повзрослел. Код: CPU MHz Dhry s Dhry/s DMIPS DMIPS/MHz f41 20 16384 6.236 2627 1.50 0.07 f45 20 16384 6.006 2728 1.55 0.08 f42 20 16384 5.581 2936 1.67 0.08 f43 20 16384 4.997 3279 1.87 0.09 f44 20 16384 4.491 3648 2.08 0.10 f44x6 20 16384 1.936 8463 4.82 0.24 f61 20 16384 1.858 8818 5.02 0.25
Dhry2 Dhry2 Opt NoOpt VAX VAX CPU MHz MIPS MIPS AMD 80386 40 13.7 4.53 0.11-0.34 IBM 486D2 50 22.4 7.89 0.16-0.45 80486 DX2 66 35.3 12.4 0.19-0.53 IBM 486BL 100 40.9 11.8 0.12-0.41 AMD 5X86 133 84.5 9.42 0.07-0.64 Pentium 75 87.1 18.9 0.25-1.16 ... Core 2 Duo 1 CP 2400 6446 1251 0.52-2.69 Core i7 4820K 3900 11867 1981 0.51-3.04 Процессор с 4-битными командами уже на пределе (f44x6), маловероятно, что в плане производительности удастся выжать из него еще хоть что-то. Разве что оптимизации добавлять в компилятор или систему команд чуть более удачную придумывать. А вот у процессора с 6-битными командами есть огромный резерв и простор для творчества (перечислю только основные моменты): - сама система команд, есть несколько вариантов, в "железе" пока реализована самая простая (и медленная); - 2 свободных слота в текущей системе команд; - при трансляции Си-в-Форт сишные циклы for/while/do-while транслируются в jz/jmp, а намного более быстрые аппаратные циклы while-repeat и do-loop не задействованы; - и, наконец, никто не запрещает выполнять по несколько команд за такт (как и в f44x6), ну а пока читается по 3 команды за такт (задел на будущее, можно и 6 сделать), но выполняется пока ровно по одной; Ну а еще сам компилятор. Все же Dhrystone оценивает не производительность процессора, а производительность связки процессор+компилятор. И тем удивительнее, что даже в таком сыром виде творческий союз "самодельный процессор"+"самодельный компилятор" не проигрывает тандему "серийный процессор"+"профессиональный компилятор". upd. Для коллекции процессор с 6-битными командами и литералами за 1-2 такта, пока еще в зачаточном состоянии, но пусть будет Код: CPU MHz Dhry s Dhry/s DMIPS DMIPS/MHz f61x3 20 16384 1.762 9299 5.29 0.26 Код программы нарезан на 18-битные порции (куски по 3 6-битных команды), 2 такта на литерал получается, если литерал целиком не помещается в текущее 18-битное слово и наползает на следующее. Кроме литералов ничего не делал.
Выдалась свободная минутка, перепрогнал Dhrystone через свои процессоры, ибо мой компилятор Си-в-Форт чуточку повзрослел.[code]CPU MHz Dhry s Dhry/s DMIPS DMIPS/MHz f41 20 16384 6.236 2627 1.50 0.07 f45 20 16384 6.006 2728 1.55 0.08 f42 20 16384 5.581 2936 1.67 0.08 f43 20 16384 4.997 3279 1.87 0.09 f44 20 16384 4.491 3648 2.08 0.10 f44x6 20 16384 1.936 8463 4.82 0.24 f61 20 16384 1.858 8818 5.02 0.25
Dhry2 Dhry2 Opt NoOpt VAX VAX CPU MHz MIPS MIPS AMD 80386 40 13.7 4.53 0.11-0.34 IBM 486D2 50 22.4 7.89 0.16-0.45 80486 DX2 66 35.3 12.4 0.19-0.53 IBM 486BL 100 40.9 11.8 0.12-0.41 AMD 5X86 133 84.5 9.42 0.07-0.64 Pentium 75 87.1 18.9 0.25-1.16 ... Core 2 Duo 1 CP 2400 6446 1251 0.52-2.69 Core i7 4820K 3900 11867 1981 0.51-3.04[/code]Процессор с 4-битными командами уже на пределе (f44x6), маловероятно, что в плане производительности удастся выжать из него еще хоть что-то. Разве что оптимизации добавлять в компилятор или систему команд чуть более удачную придумывать. А вот у процессора с 6-битными командами есть огромный резерв и простор для творчества (перечислю только основные моменты): - сама система команд, есть несколько вариантов, в "железе" пока реализована самая простая (и медленная); - 2 свободных слота в текущей системе команд; - при трансляции Си-в-Форт сишные циклы for/while/do-while транслируются в jz/jmp, а намного более быстрые аппаратные циклы while-repeat и do-loop не задействованы; - и, наконец, никто не запрещает выполнять по несколько команд за такт (как и в f44x6), ну а пока читается по 3 команды за такт (задел на будущее, можно и 6 сделать), но выполняется пока ровно по одной; Ну а еще сам компилятор. Все же Dhrystone оценивает не производительность процессора, а производительность связки процессор+компилятор. И тем удивительнее, что даже в таком сыром виде творческий союз "самодельный процессор"+"самодельный компилятор" не проигрывает тандему "серийный процессор"+"профессиональный компилятор".
upd. Для коллекции процессор с 6-битными командами и литералами за 1-2 такта, пока еще в зачаточном состоянии, но пусть будет[code]CPU MHz Dhry s Dhry/s DMIPS DMIPS/MHz f61x3 20 16384 1.762 9299 5.29 0.26[/code]Код программы нарезан на 18-битные порции (куски по 3 6-битных команды), 2 такта на литерал получается, если литерал целиком не помещается в текущее 18-битное слово и наползает на следующее. Кроме литералов ничего не делал.
|
|
|
|
Добавлено: Пт ноя 01, 2024 00:26 |
|
|
|
|
|
Заголовок сообщения: |
Re: Как сделать форт-процессор 2022 |
|
|
Кстати, наткнулся тут и вспомнил, откуда тестовая 3d-бродилка взялась. ссылка на изображениеОна там была в нескольких вариантах на Си, взял первую из них и перевел на Форт, попутно заменив float на int. Если мне не изменяет склероз, там же были сразу варианты с fixed point и текстурами.
:) Кстати, наткнулся тут и вспомнил, откуда тестовая 3d-бродилка взялась. [img]http://totalvacuum.ru/gfx.jpg[/img] [url=http://totalvacuum.ru/gfx.jpg]ссылка на изображение[/url] Она там была в нескольких вариантах на Си, взял первую из них и перевел на Форт, попутно заменив float на int. Если мне не изменяет склероз, там же были сразу варианты с fixed point и текстурами.
|
|
|
|
Добавлено: Чт июл 25, 2024 17:27 |
|
|
|
|
|
Заголовок сообщения: |
Re: Как сделать форт-процессор 2022 |
|
|
Hishnik писал(а): Ого! Это серьезно. Тут ведь еще какой интересный вывод получается. Вот в рамках одного архитектурного подхода получился набор ядер. Они показали существенно разные характеристики на Dhrystone. В принципе понятно, что там можно менять, чтобы они были еще лучше. Теперь можно пойти дальше и распространить подход на тесты, имитирующие реальные задачи. Будет аналогично - базовое ядро, тесты, модификация для улучшения характеристик в нужную сторону. Ну я в основном занимался не затачиванием процессора под Dhrystone, а ускорением традиционных для Форта примитивов, которым по понятным причинам не хватило места в системе из 16 команд. Вот в дополнение к предыдущему варианту добавил в f44x6 за такт 15 rshift (знак числа), n *, invert (dup nand), < (- 15 rshift). В результате стало еще чуточку быстрее: Код: CPU MHz Dhry s Dhry/s DMIPS DMIPS/MHz f44x6 20 16384 2.060 7953 4.53 0.23 Ну и есть понимание, чего примерно можно ожидать от процессора с чуть более широкой системой команд, в котором все базовые примитивы будут из коробки. Другими словами, я пытался нащупать некий гипотетический потолок производительности для Форт-процессоров с достаточно широким машинным словом, при этом, однако, держал в уме, что компилятор совсем слабый, а, следовательно, с коммерческим компилятором результаты должны быть гораздо выше. Ну а вообще можно двигаться как в сторону увеличения количества одновременно выполняемыых за такт команд или же увеличения количества ядер, так и в сторону увеличения разрядности машинного слова. И видно, что, например, даже небольшие (и практически бесплатные с точки зрения потребления ресурсов ПЛИС) изменения (2 команды за такт в f42x2) приводят к существенному росту скорости. Как и расширение машинного слова с 4 до 6 бит, в результате чего например f61, который выполняет ровно по одной команде, в 2-3 раза опережает обычные процессоры с 4-битными командами, да и не сильно отстает от раскочегаренного до неприличия f44x6. Причем это самый первый и самый простой вариант 6-битного процессора, есть и другие более навороченные, но они пока не завелись в ПЛИС. А так да, когда на горизонте забрезжит какая-то реальная задача, то система команд будет затачиваться именно под нее, в т.ч. добавлением новых команд, может даже экзотических. Но это на случай. если вдруг процессор общего назначения перестанет справляться. Но главное, что удалось убить сразу несколько зайцев (шучу, ни один заяц при съемках не пострадал): - убедился, что компилятор Си успешно транслирует достаточно сложный исходник, который (это тоже важно) был написан другим человеком; - обнаружил (не без удивления), что мои процессоры не сильно проигрывают обычным серийным процессорам, за такие цифры не стыдно, более того, есть понимание, что если здесь вдруг появится возможность использования коммерческого компилятора с тучей возможных оптимизаций (например, которые транслируют в условный llvm или в webassembly), то результаты, естественно, окажутся еще более впечатляющими, кстати, никто ведь не запрещает использовать Форт и Форт-ассемблер, результат в моем случае почти всегда оказывается более быстрым и компактным, если сравнивать с выхлопом от моего транслятора Си; - увидел, что связка свой-процессор/свой-компилятор (Си, Форт или любой другой) вполне жизнеспособна, даже когда процессор до неприличия простой, а компилятор Си даже не умеет константные выражения на этапе компиляции вычислять, про какие-либо оптимизации я вообще молчу, тем не менее, рано или поздно оптимизации появятся, вижу много мест, где транслятор должен рожать более красивый код; - получил инструмент, при помощи которого можно сравнивать между собой разные системы команд, раньше сравнивал при помощи 3d-бродилки, и хотя корреляция между тестами есть, но доверия к общепризнанному инструменту чуточку больше
[quote="Hishnik"]Ого! Это серьезно. Тут ведь еще какой интересный вывод получается. Вот в рамках одного архитектурного подхода получился набор ядер. Они показали существенно разные характеристики на Dhrystone. В принципе понятно, что там можно менять, чтобы они были еще лучше. Теперь можно пойти дальше и распространить подход на тесты, имитирующие реальные задачи. Будет аналогично - базовое ядро, тесты, модификация для улучшения характеристик в нужную сторону.[/quote]Ну я в основном занимался не затачиванием процессора под Dhrystone, а ускорением традиционных для Форта примитивов, которым по понятным причинам не хватило места в системе из 16 команд. Вот в дополнение к предыдущему варианту добавил в f44x6 за такт 15 rshift (знак числа), n *, invert (dup nand), < (- 15 rshift). В результате стало еще чуточку быстрее:[code]CPU MHz Dhry s Dhry/s DMIPS DMIPS/MHz f44x6 20 16384 2.060 7953 4.53 0.23[/code]Ну и есть понимание, чего примерно можно ожидать от процессора с чуть более широкой системой команд, в котором все базовые примитивы будут из коробки. Другими словами, я пытался нащупать некий гипотетический потолок производительности для Форт-процессоров с достаточно широким машинным словом, при этом, однако, держал в уме, что компилятор совсем слабый, а, следовательно, с коммерческим компилятором результаты должны быть гораздо выше. Ну а вообще можно двигаться как в сторону увеличения количества одновременно выполняемыых за такт команд или же увеличения количества ядер, так и в сторону увеличения разрядности машинного слова. И видно, что, например, даже небольшие (и практически бесплатные с точки зрения потребления ресурсов ПЛИС) изменения (2 команды за такт в f42x2) приводят к существенному росту скорости. Как и расширение машинного слова с 4 до 6 бит, в результате чего например f61, который выполняет ровно по одной команде, в 2-3 раза опережает обычные процессоры с 4-битными командами, да и не сильно отстает от раскочегаренного до неприличия f44x6. Причем это самый первый и самый простой вариант 6-битного процессора, есть и другие более навороченные, но они пока не завелись в ПЛИС. А так да, когда на горизонте забрезжит какая-то реальная задача, то система команд будет затачиваться именно под нее, в т.ч. добавлением новых команд, может даже экзотических. Но это на случай. если вдруг процессор общего назначения перестанет справляться.
Но главное, что удалось убить сразу несколько зайцев (шучу, ни один заяц при съемках не пострадал): - убедился, что компилятор Си успешно транслирует достаточно сложный исходник, который (это тоже важно) был написан другим человеком; - обнаружил (не без удивления), что мои процессоры не сильно проигрывают обычным серийным процессорам, за такие цифры не стыдно, более того, есть понимание, что если здесь вдруг появится возможность использования коммерческого компилятора с тучей возможных оптимизаций (например, которые транслируют в условный llvm или в webassembly), то результаты, естественно, окажутся еще более впечатляющими, кстати, никто ведь не запрещает использовать Форт и Форт-ассемблер, результат в моем случае почти всегда оказывается более быстрым и компактным, если сравнивать с выхлопом от моего транслятора Си; - увидел, что связка свой-процессор/свой-компилятор (Си, Форт или любой другой) вполне жизнеспособна, даже когда процессор до неприличия простой, а компилятор Си даже не умеет константные выражения на этапе компиляции вычислять, про какие-либо оптимизации я вообще молчу, тем не менее, рано или поздно оптимизации появятся, вижу много мест, где транслятор должен рожать более красивый код; - получил инструмент, при помощи которого можно сравнивать между собой разные системы команд, раньше сравнивал при помощи 3d-бродилки, и хотя корреляция между тестами есть, но доверия к общепризнанному инструменту чуточку больше :)
|
|
|
|
Добавлено: Пн май 20, 2024 01:03 |
|
|
|
|
|
Заголовок сообщения: |
Re: Как сделать форт-процессор 2022 |
|
|
Ого! Это серьезно. Тут ведь еще какой интересный вывод получается. Вот в рамках одного архитектурного подхода получился набор ядер. Они показали существенно разные характеристики на Dhrystone. В принципе понятно, что там можно менять, чтобы они были еще лучше. Теперь можно пойти дальше и распространить подход на тесты, имитирующие реальные задачи. Будет аналогично - базовое ядро, тесты, модификация для улучшения характеристик в нужную сторону.
Ого! Это серьезно. Тут ведь еще какой интересный вывод получается. Вот в рамках одного архитектурного подхода получился набор ядер. Они показали существенно разные характеристики на Dhrystone. В принципе понятно, что там можно менять, чтобы они были еще лучше. Теперь можно пойти дальше и распространить подход на тесты, имитирующие реальные задачи. Будет аналогично - базовое ядро, тесты, модификация для улучшения характеристик в нужную сторону.
|
|
|
|
Добавлено: Вс май 19, 2024 17:48 |
|
|
|
|
|
Заголовок сообщения: |
Re: Как сделать форт-процессор 2022 |
|
|
KPG писал(а): Стандартный Cи тест Coremark (для Forth тоже был перенесён и были измерения в местном топике Бенчмарка Форт систем) P.S. Таблица на сайте измерения для разных кристалов https://www.eembc.org/coremark/scores.phpCoremark пока не компилируется, т.к. до сих пор не дошли руки до указателей на функции в моем трансляторе. Но зато с полпинка завелся тест Dhrystone. Наконец-то добрался до платы с ПЛИС и прогнал Дрыстоний через свои процессоры: Код: CPU MHz Dhry s Dhry/s DMIPS DMIPS/MHz r81 20 16384 6.126 2675 1.52 0.08 f41 20 16384 7.484 2189 1.25 0.06 f42 20 16384 6.637 2469 1.41 0.07 f43 20 16384 5.466 2997 1.71 0.09 f44 20 16384 4.920 3330 1.90 0.09 f42x2 20 16384 4.620 3546 2.02 0.10 f43x6 20 16384 3.907 4193 2.39 0.12 f44x6 20 16384 2.120 7728 4.40 0.22 f61 20 16384 2.541 6448 3.67 0.18
Core 2 Duo E8500 3160 1M 0.440 1294 0.41 vax 11/780 5 1757 1 0.20
Dhry2 Dhry2 Opt NoOpt VAX VAX CPU MHz MIPS MIPS AMD 80386 40 13.7 4.53 0.11-0.34 IBM 486D2 50 22.4 7.89 0.16-0.45 80486 DX2 66 35.3 12.4 0.19-0.53 IBM 486BL 100 40.9 11.8 0.12-0.41 AMD 5X86 133 84.5 9.42 0.07-0.64 Pentium 75 87.1 18.9 0.25-1.16 ... Core 2 Duo 1 CP 2400 6446 1251 0.52-2.69 Core i7 4820K 3900 11867 1981 0.51-3.04 Для сравнения здесь же приведены цифры по "эталонному" vax11/780, core 2 duo e8500, под который скомпилировал своим транслятором и по другим процессорам (взято отсюда http://www.roylongbottom.org.uk/dhrystone%20results.htm). Из моих в списке risc c 8-битными командами (по 4 бита на код команды и register/immediate) и форт-процессоры с 4- и 6- битными командами. Процессоры f42x2/f43x6/f44x6 выполняют в точности ту же прошивку, что f42/f43/f44 соответстенно. Но f42x2 умеет выполнять одновременно до 2 команд за такт (команды 0-3, push/0-3 или push/push), f43x6 умеет за такт до 6 команд, в т.ч. n(литерал)/n call/n jz/dup(0 pick), ну а f44x6 - те же, что и в f43x6, плюс n +/n -/n @/n !/drop(0 * -)/over(1 pick)/nip(swap 0 * -), в результате работают заметно быстрее. ссылка на изображение
[quote="KPG"]Стандартный Cи тест [url=https://github.com/eembc/coremark]Coremark[/url] (для Forth тоже был перенесён и были измерения в местном топике Бенчмарка Форт систем) P.S. Таблица на сайте измерения для разных кристалов https://www.eembc.org/coremark/scores.php[/quote]Coremark пока не компилируется, т.к. до сих пор не дошли руки до указателей на функции в моем трансляторе.
Но зато с полпинка завелся тест Dhrystone. Наконец-то добрался до платы с ПЛИС и прогнал Дрыстоний через свои процессоры:[code]CPU MHz Dhry s Dhry/s DMIPS DMIPS/MHz r81 20 16384 6.126 2675 1.52 0.08 f41 20 16384 7.484 2189 1.25 0.06 f42 20 16384 6.637 2469 1.41 0.07 f43 20 16384 5.466 2997 1.71 0.09 f44 20 16384 4.920 3330 1.90 0.09 f42x2 20 16384 4.620 3546 2.02 0.10 f43x6 20 16384 3.907 4193 2.39 0.12 f44x6 20 16384 2.120 7728 4.40 0.22 f61 20 16384 2.541 6448 3.67 0.18
Core 2 Duo E8500 3160 1M 0.440 1294 0.41 vax 11/780 5 1757 1 0.20
Dhry2 Dhry2 Opt NoOpt VAX VAX CPU MHz MIPS MIPS AMD 80386 40 13.7 4.53 0.11-0.34 IBM 486D2 50 22.4 7.89 0.16-0.45 80486 DX2 66 35.3 12.4 0.19-0.53 IBM 486BL 100 40.9 11.8 0.12-0.41 AMD 5X86 133 84.5 9.42 0.07-0.64 Pentium 75 87.1 18.9 0.25-1.16 ... Core 2 Duo 1 CP 2400 6446 1251 0.52-2.69 Core i7 4820K 3900 11867 1981 0.51-3.04[/code]Для сравнения здесь же приведены цифры по "эталонному" vax11/780, core 2 duo e8500, под который скомпилировал своим транслятором и по другим процессорам (взято отсюда [url]http://www.roylongbottom.org.uk/dhrystone%20results.htm[/url]).
Из моих в списке risc c 8-битными командами (по 4 бита на код команды и register/immediate) и форт-процессоры с 4- и 6- битными командами. Процессоры f42x2/f43x6/f44x6 выполняют в точности ту же прошивку, что f42/f43/f44 соответстенно. Но f42x2 умеет выполнять одновременно до 2 команд за такт (команды 0-3, push/0-3 или push/push), f43x6 умеет за такт до 6 команд, в т.ч. n(литерал)/n call/n jz/dup(0 pick), ну а f44x6 - те же, что и в f43x6, плюс n +/n -/n @/n !/drop(0 * -)/over(1 pick)/nip(swap 0 * -), в результате работают заметно быстрее.
[img]http://totalvacuum.ru/dhryf61.jpg[/img] [url=http://totalvacuum.ru/dhryf61.jpg]ссылка на изображение[/url]
|
|
|
|
Добавлено: Вс май 19, 2024 00:18 |
|
|
|
|
|
Заголовок сообщения: |
Re: Как сделать форт-процессор 2022 |
|
|
Игры с внутренними регистрами в целях улучшить показатели в синтетических тестах в конечном итоге не дают практической пользы. Если разобраться, в итоге это приводит к добавлению аппаратного ядра, которое и выполняет основную работу, и тут его стоит аккуратно "отцепить" от процессора, чтобы не делать из универсального устройства компонент, который по сути будет крутиться в цикле CMD1 CMD2. В принципе есть варианты ускорения циклов и часто встречаются дополнительные флаги "одновременно с этой командой делать ret". Но такие флаги начинают расползаться по системе команд, портя ее внутреннюю согласованность.
Игры с внутренними регистрами в целях улучшить показатели в синтетических тестах в конечном итоге не дают практической пользы. Если разобраться, в итоге это приводит к добавлению аппаратного ядра, которое и выполняет основную работу, и тут его стоит аккуратно "отцепить" от процессора, чтобы не делать из универсального устройства компонент, который по сути будет крутиться в цикле CMD1 CMD2. В принципе есть варианты ускорения циклов и часто встречаются дополнительные флаги "одновременно с этой командой делать ret". Но такие флаги начинают расползаться по системе команд, портя ее внутреннюю согласованность.
|
|
|
|
Добавлено: Сб мар 23, 2024 22:27 |
|
|
|
|
|
Заголовок сообщения: |
Re: Как сделать форт-процессор 2022 |
|
|
Глянул их код чуть повнимательнее. Код: address opcode label comment 001000 5715C INNER n push n push 1000 0 DO 001001 003E8 1000 001002 00000 0 001003 57D58 IN1 n drop n pop 34 DROP 001004 00022 34 001005 00001 1 001006 BE37B + pop over over INC loop counter 001007 A080A xor T0 IN2 COMPARE 001008 FF39E drop push push nop 00100A FFFFE IN2 drop drop drop ; FINISH 00100B 5715C BENCH n push n push 1000 0 DO 00100C 003E8 1000 00100D 00000 0 00100E 20000 BE1 call INNER 00100F 563DE n pop nop nop 001010 00001 1 001011 BE37B + pop over over INC counter 001012 A0815 xor T0 BE2 COMPARE 001013 FF39E drop push push nop 001014 00003 jmp BE1 LOOP 001015 FFFBA BE2 drop drop drop n FINISH 001016 00007 7 001017 57020 n push ; long call and return 001018 03987 lit' EMIT Там много опечаток, например, отсутствует строка с адресом 001009 (там должен быть jmp IN1), по адресу 001014 адрес прыжка неправильный (должен быть прыжок по адресу XXXE, а не XXX3, видимо, неправильно распозналось при сканировании ), да и формат команды вызывает некоторые сомнения. На глаз там во внутреннем цикле 15-20 команд, но сложно в таком варианте оценивать, если не знать, сколько тактов выполняется каждая команда, выполняются ли они параллельно и т.д. С другой стороны у нас есть тактовая частота и время выполнения миллиона итераций. Смело перемножаем одно на другое - получаем количество тактов на итерацию во внутреннем цикле: 200*0.17=34 такта на итерацию цикла в INNER. Для сравнения 68040 и R4000 тратят вполне достойные 9 и 12 тактов соответственно, да даже 68030 с его 18 тактами на итерацию не так уж и плох. Создатели F21 пытются выйти из положения и разворачивают внутренний цикл, убирая тем самым накладные расходы на организацию цикла, в результате в общем-то простой код жиреет аж до 400 байт, но количество тактов на итерацию уменьшается всего лишь до 15. И лишь когда они задействуют вместо честного литерала свой внутренний регистр А (вручную или компилятор сам сообразил?), то получают космические 2 такта на итерацию. А у меня, например, в базовом варианте с 6-битными командами литерал весит 2 команды (и такта), еще такт на drop, ну и еще один на loop. В результате итерация весит 3 байта и длится 4 такта. А в продвинутом варианте (4- и 6-битном) всего два такта: первый на 34+drop, а второй на loop. При желании, наверное, можно и в один такт уложиться. И да, команды для реализации аппаратных циклов - это (с оговорками) условные call и ret. Например, while и do вполне можно обозвать условным call, а repeat и loop - условными ret. Разница лишь в том, что одни проверяют и меняют счетчик цикла, а другие проверяют условие. Условным call необходим полный литерал (адрес, по которому прыгать при невыполнении условия), но они выполняются лишь раз в качестве пролога перед входом в тело цикла, а условные ret литералов не требуют (адрес начала цикла берут из стека возвратов) и выполняются за такт.
Глянул их код чуть повнимательнее.[code]address opcode label comment 001000 5715C INNER n push n push 1000 0 DO 001001 003E8 1000 001002 00000 0 001003 57D58 IN1 n drop n pop 34 DROP 001004 00022 34 001005 00001 1 001006 BE37B + pop over over INC loop counter 001007 A080A xor T0 IN2 COMPARE 001008 FF39E drop push push nop 00100A FFFFE IN2 drop drop drop ; FINISH 00100B 5715C BENCH n push n push 1000 0 DO 00100C 003E8 1000 00100D 00000 0 00100E 20000 BE1 call INNER 00100F 563DE n pop nop nop 001010 00001 1 001011 BE37B + pop over over INC counter 001012 A0815 xor T0 BE2 COMPARE 001013 FF39E drop push push nop 001014 00003 jmp BE1 LOOP 001015 FFFBA BE2 drop drop drop n FINISH 001016 00007 7 001017 57020 n push ; long call and return 001018 03987 lit' EMIT[/code]Там много опечаток, например, отсутствует строка с адресом 001009 (там должен быть jmp IN1), по адресу 001014 адрес прыжка неправильный (должен быть прыжок по адресу XXXE, а не XXX3, видимо, неправильно распозналось при сканировании :) ), да и формат команды вызывает некоторые сомнения. На глаз там во внутреннем цикле 15-20 команд, но сложно в таком варианте оценивать, если не знать, сколько тактов выполняется каждая команда, выполняются ли они параллельно и т.д. С другой стороны у нас есть тактовая частота и время выполнения миллиона итераций. Смело перемножаем одно на другое - получаем количество тактов на итерацию во внутреннем цикле: 200*0.17=34 такта на итерацию цикла в INNER. Для сравнения 68040 и R4000 тратят вполне достойные 9 и 12 тактов соответственно, да даже 68030 с его 18 тактами на итерацию не так уж и плох. Создатели F21 пытются выйти из положения и разворачивают внутренний цикл, убирая тем самым накладные расходы на организацию цикла, в результате в общем-то простой код жиреет аж до 400 байт, но количество тактов на итерацию уменьшается всего лишь до 15. И лишь когда они задействуют вместо честного литерала свой внутренний регистр А (вручную или компилятор сам сообразил?), то получают космические 2 такта на итерацию. :) А у меня, например, в базовом варианте с 6-битными командами литерал весит 2 команды (и такта), еще такт на drop, ну и еще один на loop. В результате итерация весит 3 байта и длится 4 такта. А в продвинутом варианте (4- и 6-битном) всего два такта: первый на 34+drop, а второй на loop. При желании, наверное, можно и в один такт уложиться. И да, команды для реализации аппаратных циклов - это (с оговорками) условные call и ret. Например, while и do вполне можно обозвать условным call, а repeat и loop - условными ret. Разница лишь в том, что одни проверяют и меняют счетчик цикла, а другие проверяют условие. Условным call необходим полный литерал (адрес, по которому прыгать при невыполнении условия), но они выполняются лишь раз в качестве пролога перед входом в тело цикла, а условные ret литералов не требуют (адрес начала цикла берут из стека возвратов) и выполняются за такт.
|
|
|
|
Добавлено: Чт мар 21, 2024 01:25 |
|
|
|
|
|
Заголовок сообщения: |
Re: Как сделать форт-процессор 2022 |
|
|
В системе команд можно делать специальные поля, которые будут одновременно с расчетами выполнять переход. Литерал в такую команду трудно добавить, а RET или LOOP вполне можно. Но это уже получится упражнение "расставьте поля команды, чтобы было и полезно, и не слишком громоздко". В тестах понятно, что по сути работает только тело вложенного цикла, а накладные расходы идут параллельно с выполнением стековых манипуляций. Ну, оно тоже имеет право на жизнь.
В системе команд можно делать специальные поля, которые будут одновременно с расчетами выполнять переход. Литерал в такую команду трудно добавить, а RET или LOOP вполне можно. Но это уже получится упражнение "расставьте поля команды, чтобы было и полезно, и не слишком громоздко". В тестах понятно, что по сути работает только тело вложенного цикла, а накладные расходы идут параллельно с выполнением стековых манипуляций. Ну, оно тоже имеет право на жизнь.
|
|
|
|
Добавлено: Ср мар 20, 2024 17:38 |
|
|
|
|
|
Заголовок сообщения: |
Re: Как сделать форт-процессор 2022 |
|
|
Немного расшевелить тему. Попалась тут недавно древняя статья https://www.ultratechnology.com/forml93.htmlТам всё повествование вокруг да около форт-процессора F21. И в числе прочего приведен простенький тест Код: : INNER 1000 0 DO 34 DROP LOOP : : BENCH 1000 0 DO INNER LOOP 7 EMIT ; Этот тест выполняется на разных фортах и процессорах, показатели (почему-то абсолютные) времени сравниваются и делается вывод о крутости F21 и ущербности прочих процессоров. Т.к. мой форт-процессор с 6-битными командами тоже заработал, то решил испытать его (а заодно и предыдущие форт-процессоры с 4-битными командами) при помощи этого теста. Таблица результатов там такая: Код: PROCESSOR CLOCK FORTH-COMPILER OPTION SECONDS
VAX 6620 FIG 8080 (EMULATION) 15.32 H8 10 eForth 15.0 68000 7 7.6 80386 33 HS/FORTH 6.1 MuP21 100 MuP21 eForth 2.02 DRAM 3.3 80486 33 F83 in "C" 3.0 80386 33 FPC 2.8 68040 25 Yerk 2.7 F21 200 MuP21 eForth 2.02 DRAM 2.6 80386 33 TCOM (FPC) 1.7 80386 33 HS/FORTH w/optimization 1.6 no 34 DROP 80386 33 TCOM (FPC) 0.99 no 7 EMIT HP-PA Forth in "C" 0.75 68030 25 0.75 F21 200 F21 eForth STC 2.03 DRAM 0.7 R3000 33 RISC pFORTH INDIGO 0.66 F21 200 F21 eForth STC 2.04 DRAM 0.65 MuP21 100 fforth DRAM 0.45 68040 25 0.35 R3000 66 RISC pFORTH INDIGO 0.33 MuP21 100 fforth SRAM 0.3 F21 200 fforth DRAM 0.25 R4000 50 RISC pFORTH CRIMSON 0.24 80486 33 ForthCMP 0.21 no 34 DROP MuP21 100 fforth **1 DRAM 0.19 F21 200 fforth SRAM 0.17 MuP21 100 fforth **1 SRAM 0.14 F21 200 fforth **1 DRAM 0.137 R4000 100 RISC pFORTH CRIMSON 0.12 F21 200 fforth **1 SRAM 0.077 MuP21 100 fforth **2 DRAM 0.027 MuP21 100 fforth **2 SRAM 0.02 F21 200 fforth **2 DRAM 0.02 F21 200 fforth **2 SRAM 0.01 А для моих подопечных получились такие цифры: Код: f41/f42 20 uforth 1.09 22 такта на итерацию f43/f44 20 uforth 1.00 20 тактов на итерацию f61 20 uforth 0.199 4 такта на итерацию И получается, что если не рассматривать разные ухищрения вроде разворачивания цикла и использования регистра вместо честной записи числа в стек, то, например, f61 практически не уступает по времени процессору F21 даже несмотря на 10-кратно меньшую тактовую частоту (20 против 200МГц), да и процессоры с 4-битными командами уступают всего лишь в несколько раз. Кроме того, специально обученные форт-процессоры f4/f6, способные выполнять несколько команд за такт, выполняют тот же самый неоптимизированный код, затрачивая на итерацию всего лишь 2 такта Т.е. если привести частоты к одному знаменателю, то будет ровно такой же результат, как и у F21 с развернутыми циклами и задействованным регистром А, т.е. те же самые 2 такта на итерацию. Другими словами, F21 выполняет оптимизированный код, а f4/f6 - обычный неоптимизированный, но производительность одинаковая. Еще забавно, что если выровнять частоты, то R4000 (MIPS?), 68040, а может и еще какие-то процессоры с каким-то левым фортом окажутся быстрее, чем F21 с родным фортом
Немного расшевелить тему.
Попалась тут недавно древняя статья [url]https://www.ultratechnology.com/forml93.html[/url] Там всё повествование вокруг да около форт-процессора F21. И в числе прочего приведен простенький тест[code]: INNER 1000 0 DO 34 DROP LOOP : : BENCH 1000 0 DO INNER LOOP 7 EMIT ;[/code]Этот тест выполняется на разных фортах и процессорах, показатели (почему-то абсолютные) времени сравниваются и делается вывод о крутости F21 и ущербности прочих процессоров. :) Т.к. мой форт-процессор с 6-битными командами тоже заработал, то решил испытать его (а заодно и предыдущие форт-процессоры с 4-битными командами) при помощи этого теста. Таблица результатов там такая:[code]PROCESSOR CLOCK FORTH-COMPILER OPTION SECONDS
VAX 6620 FIG 8080 (EMULATION) 15.32 H8 10 eForth 15.0 68000 7 7.6 80386 33 HS/FORTH 6.1 MuP21 100 MuP21 eForth 2.02 DRAM 3.3 80486 33 F83 in "C" 3.0 80386 33 FPC 2.8 68040 25 Yerk 2.7 F21 200 MuP21 eForth 2.02 DRAM 2.6 80386 33 TCOM (FPC) 1.7 80386 33 HS/FORTH w/optimization 1.6 no 34 DROP 80386 33 TCOM (FPC) 0.99 no 7 EMIT HP-PA Forth in "C" 0.75 68030 25 0.75 F21 200 F21 eForth STC 2.03 DRAM 0.7 R3000 33 RISC pFORTH INDIGO 0.66 F21 200 F21 eForth STC 2.04 DRAM 0.65 MuP21 100 fforth DRAM 0.45 68040 25 0.35 R3000 66 RISC pFORTH INDIGO 0.33 MuP21 100 fforth SRAM 0.3 F21 200 fforth DRAM 0.25 R4000 50 RISC pFORTH CRIMSON 0.24 80486 33 ForthCMP 0.21 no 34 DROP MuP21 100 fforth **1 DRAM 0.19 F21 200 fforth SRAM 0.17 MuP21 100 fforth **1 SRAM 0.14 F21 200 fforth **1 DRAM 0.137 R4000 100 RISC pFORTH CRIMSON 0.12 F21 200 fforth **1 SRAM 0.077 MuP21 100 fforth **2 DRAM 0.027 MuP21 100 fforth **2 SRAM 0.02 F21 200 fforth **2 DRAM 0.02 F21 200 fforth **2 SRAM 0.01[/code]А для моих подопечных получились такие цифры:[code]f41/f42 20 uforth 1.09 22 такта на итерацию f43/f44 20 uforth 1.00 20 тактов на итерацию f61 20 uforth 0.199 4 такта на итерацию[/code] И получается, что если не рассматривать разные ухищрения вроде разворачивания цикла и использования регистра вместо честной записи числа в стек, то, например, f61 практически не уступает по времени процессору F21 даже несмотря на 10-кратно меньшую тактовую частоту (20 против 200МГц), да и процессоры с 4-битными командами уступают всего лишь в несколько раз. :) Кроме того, специально обученные форт-процессоры f4/f6, способные выполнять несколько команд за такт, выполняют тот же самый неоптимизированный код, затрачивая на итерацию всего лишь 2 такта :) Т.е. если привести частоты к одному знаменателю, то будет ровно такой же результат, как и у F21 с развернутыми циклами и задействованным регистром А, т.е. те же самые 2 такта на итерацию. Другими словами, F21 выполняет оптимизированный код, а f4/f6 - обычный неоптимизированный, но производительность одинаковая. Еще забавно, что если выровнять частоты, то R4000 (MIPS?), 68040, а может и еще какие-то процессоры с каким-то левым фортом окажутся быстрее, чем F21 с родным фортом :)
|
|
|
|
Добавлено: Ср мар 20, 2024 01:51 |
|
|
|
|
|
Заголовок сообщения: |
Re: Как сделать форт-процессор 2022 |
|
|
KPG писал(а): А, чем "плох" вариант испльзования Форт для для трансляции Си? Могу скинуть свой вариант прототипа LCC -> SPf4 (делался на основе C2Forth on Mpe Ltd с их сайта) и вариант от Михаила. (он преобразовывал LCC фронт-end в код SPF4), у меня LCC от Си (сборка на PellesC), а библиотеки (stdlib, stdio ...) уже на SPF4 (топик есть на местном форуме) Да я вроде не говорил, что "плох" И тем не менее, компилятор Си лучше писать на Си, ведь проверка самокомпилируемости - это едва ли не лучший тест, проверяющий работоспособность. А во вторых, "использование Форт для трансляции Си" автоматически получится "на сдачу" (выхлоп-то на Форте! ) после того, как компилятор будет способен компировать сам себя Понятно, что код еще придется шлифануть напильником, чтобы он читался и попроще был, но тем не менее... Реализации Си-в-Форт на Форте было бы интересно посмотреть, здесь на форуме вроде была соответствующая тема, но ссылки там давно протухли. Про с2forth от mpe я вроде читал когда-то давно, что-то такое припоминаю смутно, там у них кажись даже float не завезли, но могу ошибаться. И оригинальный LCC вроде смотрел, мне он показался каким-то громоздким.
[quote="KPG"]А, чем "плох" вариант испльзования Форт для для трансляции Си? Могу скинуть свой вариант прототипа LCC -> SPf4 (делался на основе C2Forth on Mpe Ltd с их сайта) и вариант от Михаила. (он преобразовывал LCC фронт-end в код SPF4), у меня LCC от Си (сборка на PellesC), а библиотеки (stdlib, stdio ...) уже на SPF4 (топик есть на местном форуме)[/quote]Да я вроде не говорил, что "плох" :) И тем не менее, компилятор Си лучше писать на Си, ведь проверка самокомпилируемости - это едва ли не лучший тест, проверяющий работоспособность. А во вторых, "использование Форт для трансляции Си" автоматически получится "на сдачу" (выхлоп-то на Форте! :) ) после того, как компилятор будет способен компировать сам себя :) Понятно, что код еще придется шлифануть напильником, чтобы он читался и попроще был, но тем не менее... Реализации Си-в-Форт на Форте было бы интересно посмотреть, здесь на форуме вроде была соответствующая тема, но ссылки там давно протухли. Про с2forth от mpe я вроде читал когда-то давно, что-то такое припоминаю смутно, там у них кажись даже float не завезли, но могу ошибаться. И оригинальный LCC вроде смотрел, мне он показался каким-то громоздким. :)
|
|
|
|
Добавлено: Сб сен 30, 2023 19:50 |
|
|
|
|
|
Заголовок сообщения: |
Re: Как сделать форт-процессор 2022 |
|
|
Total Vacuum писал(а): Собственно, небольшая проба пера с трансляцией си-в-форт.. А, чем "плох" вариант испльзования Форт для для трансляции Си? Могу скинуть свой вариант прототипа LCC -> SPf4 (делался на основе C2Forth on Mpe Ltd с их сайта) и вариант от Михаила. (он преобразовывал LCC фронт-end в код SPF4), у меня LCC от Си (сборка на PellesC), а библиотеки (stdlib, stdio ...) уже на SPF4 (топик есть на местном форуме) Total Vacuum писал(а): Полезный инструмент вырисовывается. Даже несмотря на его относительную примитивность и слабое качество получаемого кода. Так что будет и под мой форт-процессор простенький компилятор си. Да, тоже столкнулся, что и Макро-оптимизатор в SPF4 уже не справляется с оптимизацией полученного кода SPF4. На VFX Forth не проверял - может там лучше это получается. А, работу макро-оптимизатора в SPF4, вероятно, может объяснить только Михаил. Был ещё интересный проект F-- для использования Форт и Си совместно. P.S. А, вообще, более интересен вариант транспиляции Форт в Си. В этом направлении тоже существуют некоторые разработки, начиная от Timbre где Форт код по правилам на Форт подобном языке преобразуется в Си. Я тут немного "увлёкся" сборкой Linux Puppy (Xenial) с варианта использования собирания GLibc-2.33 из исходников для запуска, В этом топике сообщения, но похоже без сборки Xorg (и возможно ещё чего либо) этот вариант не запустить. Сейчас думаю как запустить вентилятор в буке, чтобы при нагрузке бук можно было использовать.
[quote="Total Vacuum"]Собственно, небольшая проба пера с трансляцией си-в-форт..[/quote] А, чем "плох" вариант испльзования Форт для для трансляции Си? Могу скинуть свой вариант прототипа LCC -> SPf4 (делался на основе C2Forth on Mpe Ltd с их сайта) и вариант от Михаила. (он преобразовывал LCC фронт-end в код SPF4), у меня LCC от Си (сборка на PellesC), а библиотеки (stdlib, stdio ...) уже на SPF4 (топик есть на местном форуме)
[quote="Total Vacuum"]Полезный инструмент вырисовывается. Даже несмотря на его относительную примитивность и слабое качество получаемого кода. :) Так что будет и под мой форт-процессор простенький компилятор си.[/quote] Да, тоже столкнулся, что и Макро-оптимизатор в SPF4 уже не справляется с оптимизацией полученного кода SPF4. На VFX Forth не проверял - может там лучше это получается. А, работу макро-оптимизатора в SPF4, вероятно, может объяснить только Михаил. :)
Был ещё интересный проект [url=https://fminus.sourceforge.net/]F--[/url] для использования Форт и Си совместно.
P.S. А, вообще, более интересен вариант транспиляции Форт в Си. В этом направлении тоже существуют некоторые разработки, начиная от Timbre где Форт код по правилам на Форт подобном языке преобразуется в Си.
Я тут немного "увлёкся" сборкой Linux Puppy (Xenial) с варианта использования собирания GLibc-2.33 из исходников для запуска, [url=https://forum.puppyrus.org/index.php?topic=24137.msg187077#msg187077]В этом топике сообщения[/url], но похоже без сборки Xorg (и возможно ещё чего либо) этот вариант не запустить. Сейчас думаю как запустить вентилятор в буке, чтобы при нагрузке бук можно было использовать.
|
|
|
|
Добавлено: Пт сен 29, 2023 12:31 |
|
|
|
|
|
Заголовок сообщения: |
Re: Как сделать форт-процессор 2022 |
|
|
Ну так и форт-процессор в идеале вроде как не гигантский... Собственно, небольшая проба пера с трансляцией си-в-форт. Например, такой код Код: void emit ( char c ) ; void type ( char * s ) ;
int i ;
struct node { char n ; struct node * next ; } * list , nodes [ 256 ] ;
void main ( ) { for ( i = 0 ; i < 256 ; i = i + 1 ) nodes [ i ] . n = i ;
nodes [ 'l' ] . next = & nodes [ 'i' ] ; nodes [ 'i' ] . next = & nodes [ 's' ] ; nodes [ 's' ] . next = & nodes [ 't' ] ; nodes [ 't' ] . next = 0 ;
list = & nodes [ 'l' ] ;
while ( list ) { emit ( list -> n ) ; type ( "->" ) ; list = list -> next ; }
type ( "NULL" ) ; } превращается в такое (форматирование сделано вручную): Код: create i 1 cells allot create list 1 cells allot create nodes 512 cells allot
: main i 0 over ! @ drop begin i @ 256 < while nodes i @ 16 * + 0 + i @ over c! c@ drop i i @ 1 + over ! @ drop repeat
nodes 'l' 16 * + 8 + nodes 'i' 16 * + over ! @ drop nodes 'i' 16 * + 8 + nodes 's' 16 * + over ! @ drop nodes 's' 16 * + 8 + nodes 't' 16 * + over ! @ drop nodes 't' 16 * + 8 + 0 over ! @ drop
list nodes 'l' 16 * + over ! @ drop
begin list @ while list @ 0 + c@ emit s" ->" type list list @ 8 + @ over ! @ drop repeat
s" NULL" type ; main выводит: Код: l->i->s->t->NULL Безусловно, выхлоп без каких-либо намеков на оптимизации, но самое главное, что уже работает (например, можно здесь протестировать). Невооруженным взглядом видна масса лишнего кода. Дальше могут быть разные варианты: - оставить в таком виде, если скорость и размер кода не критичны; - добавить нужные оптимизации в компилятор - не ранее, чем заработает весь запланированный функционал; - набросать отдельную утилиту, которая подчищает лишний код; - вручную оптимизировать узкие места выхлопа. Например, может получиться что-то вроде такого: Код: create i 1 cells allot create list 1 cells allot create nodes 512 cells allot
: main 0 i ! begin i @ 256 < while i @ nodes i @ 16 * + c! i @ 1 + i ! repeat
nodes 'i' 16 * + nodes 'l' 16 * + 8 + ! nodes 's' 16 * + nodes 'i' 16 * + 8 + ! nodes 't' 16 * + nodes 's' 16 * + 8 + ! 0 nodes 't' 16 * + 8 + !
nodes 'l' 16 * + list !
begin list @ while list @ c@ emit s" ->" type list @ 8 + @ list ! repeat
s" NULL" type ;
main Далее, если надо уменьшить размер или повысить читаемость кода, можно обыграть: Код: : nodes[i] 16 * nodes + ; : .n ; : .next 8 + ; : ->n @ .n ; : ->next @ .next ; и т.д. и т.п. Ну или, допустим, для факториала Код: void recurse ( ) ; void cr ( ) ; void emit ( char c ) ;
int fac ( char n ) { if ( n ) return n * recurse ( n - 1 ) ; else return 1 ; }
int n , r ;
void main ( ) { n = 6 ; while ( n ) { n = n - 1 ; r = fac ( n ) ; while ( r ) { emit ( '.' ) ; r = r - 1 ; } cr ( ) ; } } получаем Код: : fac 0 pick if 0 pick 1 pick 1 - recurse * nip exit else 1 nip exit then ; create n 1 cells allot create r 1 cells allot : main n 6 over ! @ drop begin n @ while n n @ 1 - over ! @ drop r n @ fac over ! @ drop begin r @ while '.' emit r r @ 1 - over ! @ drop repeat cr repeat ; main , которое после пары ручных правок превращается в Код: : fac dup if dup dup 1 - recurse * else 1 then nip ; create n 1 cells allot create r 1 cells allot : main 6 n ! begin n @ while n @ 1 - n ! n @ fac r ! begin r @ while '.' emit r @ 1 - r ! repeat cr repeat ; main Полезный инструмент вырисовывается. Даже несмотря на его относительную примитивность и слабое качество получаемого кода. Так что будет и под мой форт-процессор простенький компилятор си.
:D Ну так и форт-процессор в идеале вроде как не гигантский...
Собственно, небольшая проба пера с трансляцией си-в-форт. Например, такой код[code]void emit ( char c ) ; void type ( char * s ) ;
int i ;
struct node { char n ; struct node * next ; } * list , nodes [ 256 ] ;
void main ( ) { for ( i = 0 ; i < 256 ; i = i + 1 ) nodes [ i ] . n = i ;
nodes [ 'l' ] . next = & nodes [ 'i' ] ; nodes [ 'i' ] . next = & nodes [ 's' ] ; nodes [ 's' ] . next = & nodes [ 't' ] ; nodes [ 't' ] . next = 0 ;
list = & nodes [ 'l' ] ;
while ( list ) { emit ( list -> n ) ; type ( "->" ) ; list = list -> next ; }
type ( "NULL" ) ; }[/code]превращается в такое (форматирование сделано вручную):[code]create i 1 cells allot create list 1 cells allot create nodes 512 cells allot
: main i 0 over ! @ drop begin i @ 256 < while nodes i @ 16 * + 0 + i @ over c! c@ drop i i @ 1 + over ! @ drop repeat
nodes 'l' 16 * + 8 + nodes 'i' 16 * + over ! @ drop nodes 'i' 16 * + 8 + nodes 's' 16 * + over ! @ drop nodes 's' 16 * + 8 + nodes 't' 16 * + over ! @ drop nodes 't' 16 * + 8 + 0 over ! @ drop
list nodes 'l' 16 * + over ! @ drop
begin list @ while list @ 0 + c@ emit s" ->" type list list @ 8 + @ over ! @ drop repeat
s" NULL" type ; main[/code]выводит:[code]l->i->s->t->NULL[/code]Безусловно, выхлоп без каких-либо намеков на оптимизации, но самое главное, что уже работает (например, можно [url=https://www.jdoodle.com/execute-forth-online/]здесь[/url] протестировать). Невооруженным взглядом видна масса лишнего кода. Дальше могут быть разные варианты: - оставить в таком виде, если скорость и размер кода не критичны; - добавить нужные оптимизации в компилятор - не ранее, чем заработает весь запланированный функционал; - набросать отдельную утилиту, которая подчищает лишний код; - вручную оптимизировать узкие места выхлопа. Например, может получиться что-то вроде такого:[code]create i 1 cells allot create list 1 cells allot create nodes 512 cells allot
: main 0 i ! begin i @ 256 < while i @ nodes i @ 16 * + c! i @ 1 + i ! repeat
nodes 'i' 16 * + nodes 'l' 16 * + 8 + ! nodes 's' 16 * + nodes 'i' 16 * + 8 + ! nodes 't' 16 * + nodes 's' 16 * + 8 + ! 0 nodes 't' 16 * + 8 + !
nodes 'l' 16 * + list !
begin list @ while list @ c@ emit s" ->" type list @ 8 + @ list ! repeat
s" NULL" type ;
main[/code]Далее, если надо уменьшить размер или повысить читаемость кода, можно обыграть:[code]: nodes[i] 16 * nodes + ; : .n ; : .next 8 + ; : ->n @ .n ; : ->next @ .next ;[/code]и т.д. и т.п.
Ну или, допустим, для факториала[code]void recurse ( ) ; void cr ( ) ; void emit ( char c ) ;
int fac ( char n ) { if ( n ) return n * recurse ( n - 1 ) ; else return 1 ; }
int n , r ;
void main ( ) { n = 6 ; while ( n ) { n = n - 1 ; r = fac ( n ) ; while ( r ) { emit ( '.' ) ; r = r - 1 ; } cr ( ) ; } }[/code]получаем[code]: fac 0 pick if 0 pick 1 pick 1 - recurse * nip exit else 1 nip exit then ; create n 1 cells allot create r 1 cells allot : main n 6 over ! @ drop begin n @ while n n @ 1 - over ! @ drop r n @ fac over ! @ drop begin r @ while '.' emit r r @ 1 - over ! @ drop repeat cr repeat ; main[/code], которое после пары ручных правок превращается в[code]: fac dup if dup dup 1 - recurse * else 1 then nip ; create n 1 cells allot create r 1 cells allot : main 6 n ! begin n @ while n @ 1 - n ! n @ fac r ! begin r @ while '.' emit r @ 1 - r ! repeat cr repeat ; main[/code] Полезный инструмент вырисовывается. Даже несмотря на его относительную примитивность и слабое качество получаемого кода. :) Так что будет и под мой форт-процессор простенький компилятор си.
|
|
|
|
Добавлено: Пт сен 29, 2023 00:37 |
|
|
|
|
|
Заголовок сообщения: |
Re: Как сделать форт-процессор 2022 |
|
|
Total Vacuum писал(а): tinytapeout - классная задумка, но я до такого не дорос еще ПЛИС все-таки лучше. Tinytapeout слишком маленький, просто чрезмерно. Одно название "микросхема", а по сути схема на дискретных компонентах не так уж сильно будет отличаться - тоже кремний.
[quote="Total Vacuum"]tinytapeout - классная задумка, но я до такого не дорос еще [/quote] ПЛИС все-таки лучше. Tinytapeout слишком маленький, просто чрезмерно. Одно название "микросхема", а по сути схема на дискретных компонентах не так уж сильно будет отличаться - тоже кремний.
|
|
|
|
Добавлено: Вс сен 24, 2023 15:03 |
|
|
|
|
|
Заголовок сообщения: |
Re: Как сделать форт-процессор 2022 |
|
|
KPG писал(а): Можно оттолкнуться от ранеее уже "сделанных" вариантов (и в рамках обсуждения на местном форуме c LCC -> Forth) или появишихся оригинальных как СС64 и/или вроде в DuskOS Мне как-то не попадались трансляторы си-в-форт. Ну или просто плохо искал Да в любом случае проще свой транслятор написать, чем в чужом разбираться. Уже сейчас простые примеры типа факториала компилируются в uf \ micro forth \ (при желании и в классический форт тривиально оттранслируются) и работают, нужно лишь усилие, чтобы заставить себя довести до ума. А кроме того, любой уважающий себя компилятор должен уметь компилировать сам себя, поэтому компилятор си должен быть написан на си (я пока сам себя не компилирую, поэтому временно на tcc делаю), а duskos и cc64 вроде на форте написаны, если я правильно путаю. tinytapeout - классная задумка, но я до такого не дорос еще
[quote="KPG"]Можно оттолкнуться от ранеее уже "сделанных" вариантов (и в рамках обсуждения на местном форуме c LCC -> Forth) или появишихся оригинальных как СС64 и/или вроде в DuskOS[/quote]Мне как-то не попадались трансляторы си-в-форт. Ну или просто плохо искал :) Да в любом случае проще свой транслятор написать, чем в чужом разбираться. Уже сейчас простые примеры типа факториала компилируются в uf \ micro forth \ (при желании и в классический форт тривиально оттранслируются) и работают, нужно лишь усилие, чтобы заставить себя довести до ума. А кроме того, любой уважающий себя компилятор должен уметь компилировать сам себя, поэтому компилятор си должен быть написан на си (я пока сам себя не компилирую, поэтому временно на tcc делаю), а duskos и cc64 вроде на форте написаны, если я правильно путаю. :)
tinytapeout - классная задумка, но я до такого не дорос еще :)
|
|
|
|
Добавлено: Вс сен 24, 2023 13:31 |
|
|
|
|
|
Заголовок сообщения: |
Re: Как сделать форт-процессор 2022 |
|
|
Total Vacuum писал(а): Надо будет как-нибудь собраться и написать свой транслятор си-в-форт, чтобы на моем процессоре си-шные тесты гонять Можно оттолкнуться от ранеее уже "сделанных" вариантов (и в рамках обсуждения на местном форуме c LCC -> Forth) или появишихся оригинальных как СС64 и/или вроде в DuskOS или задействоваать библиотеки с оптимизациями подобные LibJit. P.S. Из топика Заказ собственных микросхем через TinyTapeout кто то заказал и микросхему своего проекта с RayCasting https://github.com/algofoogle/tt04-raybox-zerohttps://github.com/algofoogle/raybox-zeroПри желании, вероятно возможно, и заказать свой Форт процессор в кремнии на исполнение в следующий TT05
[quote="Total Vacuum"]Надо будет как-нибудь собраться и написать свой транслятор си-в-форт, чтобы на моем процессоре си-шные тесты гонять :)[/quote] Можно оттолкнуться от ранеее уже "сделанных" вариантов (и в рамках обсуждения на местном форуме c LCC -> Forth) или появишихся оригинальных как СС64 и/или вроде в DuskOS или задействоваать библиотеки с оптимизациями подобные LibJit.
P.S. Из топика [url=http://www.nedopc.org/forum/viewtopic.php?f=68&t=21972&start=15]Заказ собственных микросхем через TinyTapeout[/url] кто то заказал и микросхему своего проекта с RayCasting
https://github.com/algofoogle/tt04-raybox-zero https://github.com/algofoogle/raybox-zero [img]https://github.com/algofoogle/tt04-raybox-zero/raw/main/doc/fpga-vs-sim.jpg[/img]
При желании, вероятно возможно, и заказать свой Форт процессор в кремнии на исполнение в [url=https://github.com/TinyTapeout/tt05-submission-template]следующий TT05[/url] :)
|
|
|
|
Добавлено: Сб сен 09, 2023 12:49 |
|
|
|
|