Автор |
Сообщение |
|
|
Заголовок сообщения: |
Re: Новый подход к генерации Фортом машинного кода |
|
|
В слове "машинный код" несколько ошибок... Правильно писать "мышиный кот"...
В слове "машинный код" несколько ошибок... Правильно писать "мышиный кот"... :D
|
|
|
|
Добавлено: Ср окт 27, 2021 11:48 |
|
|
|
|
|
Заголовок сообщения: |
Re: Новый подход к генерации Фортом машинного кода |
|
|
Немного сподвигся погонять код проекта https://github.com/anse1/firmforthВ целом на текущих собранных LibFirm и Cparser с Github реп в рамках LiveCD Linux Puppy (если убрать добавочные биндинги команд в цикле запуска main в FirmForth.c) работает консоль - Форт цикла Interpret и создаются .so файлы а дальше появляются ньюансы по тому что считать работоспособным в рамках используемого окружения в Форт коде в текущих реалиях LibFirm и Cparser для FirmForth (вероятно ранее данный проект был, а возможно и сейчас полностью работоспобен и всё дело в моих кривых телодвижениях по его опробации) т.е. Си (Форт) код рабочий на примитивах системы и есть клавиатурный ввод/вывод с печатью по Форт-точке и вводом слов в словарь и добавлению слов в него. но не так хороший как хотелось бы (есть, и зачастую, вылеты Форт системы с терминального диалога с пользователем и загрузки Форт кода в виде расширения системы) P.S. Но, думаю, не всё в этом варианте ускорения Форт безнaдёжно, в силу сравнения вычислений 40-го числa Фибоначи в Форт и сравнении сколько на него потратит времени gForth. (интересно дальше оценить в других Форт алгоритмах) Правда собранный FirmForth размером под 3,8Мб немного пугает, но результирующий бинарный код вполне получается компактным - на уровне размера исходной Форт программы. (вроде как собирается с ассемблера в файлы .so например) Хаб LibFirm на Github не так заполнен примерами проектов: https://github.com/libfirm
Немного сподвигся погонять код проекта https://github.com/anse1/firmforth В целом на текущих собранных LibFirm и Cparser с Github реп в рамках LiveCD Linux Puppy (если убрать добавочные биндинги команд в цикле запуска main в FirmForth.c) работает консоль - Форт цикла Interpret и создаются .so файлы а дальше появляются ньюансы по тому что считать работоспособным в рамках используемого окружения в Форт коде в текущих реалиях LibFirm и Cparser для FirmForth :) (вероятно ранее данный проект был, а возможно и сейчас полностью работоспобен и всё дело в моих кривых телодвижениях по его опробации) т.е. Си (Форт) код рабочий на примитивах системы и есть клавиатурный ввод/вывод с печатью по Форт-точке и вводом слов в словарь и добавлению слов в него. но не так хороший как хотелось бы (есть, и зачастую, вылеты Форт системы с терминального диалога с пользователем и загрузки Форт кода в виде расширения системы)
P.S. Но, думаю, не всё в этом варианте ускорения Форт безнaдёжно, в силу сравнения вычислений 40-го числa Фибоначи в Форт и сравнении сколько на него потратит времени gForth. :) (интересно дальше оценить в других Форт алгоритмах) Правда собранный FirmForth размером под 3,8Мб немного пугает, но результирующий бинарный код вполне получается компактным - на уровне размера исходной Форт программы. (вроде как собирается с ассемблера в файлы .so например)
Хаб LibFirm на Github не так заполнен примерами проектов: https://github.com/libfirm
|
|
|
|
Добавлено: Ср окт 06, 2021 17:43 |
|
|
|
|
|
Заголовок сообщения: |
Re: Новый подход к генерации Фортом машинного кода |
|
|
Хочу сказать огромное спасибо этой теме! Прочитав перевод статьи Антона Эртла я всерьёз задумался о том, что именно может сделать автоматически оптимизатор Форта и нашёл неожиданное решение для Каллисто-2, основанное на комбинации шитого и подпрограммного кода. Интересно, был ли у кого-нибудь опыт подобного? Если кому интересны подробности с набросками кода, вот цитата из моей темы Каллисто-2 в Контакте: Цитата: Изначально в Каллисто-2 был предусмотрен шитый код в области двоичных данных. Память программ же отводилась только для примитивов и служебной области — таблицы свёрток, преобразующей байт поля кода в адрес обработчика. Такой подход сильно нагружал область байтовых данных. Сегодня ночью ко мне пришло более совершенное решение, экономящее область данных и повышающее быстродействие Каллисто-2. Если кратко, то предлагается в памяти программ использовать процедурный код, а в памяти данных — старый добрый шитый код, как раньше.
Вот, как это будет устроено. Допустим, у нас есть слово высокого уровня COUNT: : COUNT ↑ 1+ ↔ C@ ;
В таблице свёрток есть адрес обработчика этого слова, например ZCount. Через эту таблицу COUNT будет вызывать высокоуровневый код из области данных. Поэтому он будет обращаться к реализации Count в подпрограммном коде через преамбулу, КБП9 передаёт управление на NEXT:
ZCount: ПП Count КБП9 Count: ПП Dup 1 + ↔ БП Cat
Адрес Count используется для обращения к Count из подпрограммного кода в памяти программ. Такие же метки Dup и Cat используются для подпрограммной реализации примитивов ↑ и C@ например:
Cat: ПА ↔ КИПА В/О
Обращение к последнему слову C@ происходит через БП. Это обычная оптимизация более длинной и долгой фразы ПП Cat В/О. В теории даже от БП можно избавиться, размещая обработчики друг за другом. Простые обработчики слов 1+ и ↔ помещены прямо в код COUNT, в виде команд на языке МК-161.
Конечно же, для ↑ 1+ ↔ C@ существуют свои трёхшаговые «преамбулы» для вызова из шитого кода. Впрочем, адресный интерпретатор может при вызове обработчика сам делать КПП вместо КБП, самостоятельно делая NEXT после возврата. Над этим ещё подумаю, но в целом картина оптимистичная и существенно повышает быстродействие Каллисто. Пока оптимизацию буду делать вручную, но сама возможность перехода на более быстрый и хорошо оптимизирующийся подпрограммный код, с сохранением исполнения шитого кода из области данных (основное требование гарвардской архитектуры 8051), обрадовал. Пользуясь случаем, поздравляю всех с 23 февраля. Побольше вдохновляющих тем!
Хочу сказать огромное спасибо этой теме! Прочитав перевод статьи Антона Эртла я всерьёз задумался о том, что именно может сделать автоматически оптимизатор Форта и нашёл неожиданное решение для Каллисто-2, основанное на комбинации шитого и подпрограммного кода. Интересно, был ли у кого-нибудь опыт подобного?
Если кому интересны подробности с набросками кода, вот цитата из моей темы Каллисто-2 в Контакте: [quote]Изначально в Каллисто-2 был предусмотрен шитый код в области двоичных данных. Память программ же отводилась только для примитивов и служебной области — таблицы свёрток, преобразующей байт поля кода в адрес обработчика. Такой подход сильно нагружал область байтовых данных. Сегодня ночью ко мне пришло более совершенное решение, экономящее область данных и повышающее быстродействие Каллисто-2. Если кратко, то предлагается в памяти программ использовать процедурный код, а в памяти данных — старый добрый шитый код, как раньше.
Вот, как это будет устроено. Допустим, у нас есть слово высокого уровня COUNT: : COUNT ↑ 1+ ↔ C@ ;
В таблице свёрток есть адрес обработчика этого слова, например ZCount. Через эту таблицу COUNT будет вызывать высокоуровневый код из области данных. Поэтому он будет обращаться к реализации Count в подпрограммном коде через преамбулу, КБП9 передаёт управление на NEXT:
ZCount: ПП Count КБП9 Count: ПП Dup 1 + ↔ БП Cat
Адрес Count используется для обращения к Count из подпрограммного кода в памяти программ. Такие же метки Dup и Cat используются для подпрограммной реализации примитивов ↑ и C@ например:
Cat: ПА ↔ КИПА В/О
Обращение к последнему слову C@ происходит через БП. Это обычная оптимизация более длинной и долгой фразы ПП Cat В/О. В теории даже от БП можно избавиться, размещая обработчики друг за другом. Простые обработчики слов 1+ и ↔ помещены прямо в код COUNT, в виде команд на языке МК-161.
Конечно же, для ↑ 1+ ↔ C@ существуют свои трёхшаговые «преамбулы» для вызова из шитого кода. Впрочем, адресный интерпретатор может при вызове обработчика сам делать КПП вместо КБП, самостоятельно делая NEXT после возврата. Над этим ещё подумаю, но в целом картина оптимистичная и существенно повышает быстродействие Каллисто.[/quote] Пока оптимизацию буду делать вручную, но сама возможность перехода на более быстрый и хорошо оптимизирующийся подпрограммный код, с сохранением исполнения шитого кода из области данных (основное требование гарвардской архитектуры 8051), обрадовал. Пользуясь случаем, поздравляю всех с 23 февраля. :D Побольше вдохновляющих тем!
|
|
|
|
Добавлено: Сб фев 23, 2019 04:02 |
|
|
|
|
|
Заголовок сообщения: |
Re: Новый подход к генерации Фортом машинного кода |
|
|
Кто хотел LLVM "Форт"? :)
[url=https://github.com/riywo/llforth]LLForth Experimental Forth implementation in LLVM.[/url]
Немного другой подход и инструментарий [url=https://github.com/anse1/firmforth]FirmForth[/url]
P.S. Ещё, возможно, интересно [url=https://github.com/uho/flk]FLK is an optimizing native code forth compiler.[/url]
|
|
|
|
Добавлено: Пт фев 22, 2019 02:40 |
|
|
|
|
|
Заголовок сообщения: |
Re: |
|
|
Хищник писал(а): Ну и тогда уж, до кучи. Вот мы сейчас смотрим на LLVM с целью написания back-endа для процессорного ядра QuarkR. продвижение LLVM back-end существует? В репозитарии LLVM есть реализация front-enda некоторого стекового языка Stacker. P.S. В начале декабря вышла 3.0 версия LLVM.
[quote="Хищник"]Ну и тогда уж, до кучи. Вот мы сейчас смотрим на LLVM с целью написания back-endа для процессорного ядра QuarkR. [/quote] продвижение LLVM back-end существует? В репозитарии LLVM есть реализация front-enda некоторого стекового языка Stacker.
P.S. В начале декабря вышла 3.0 версия LLVM.
|
|
|
|
Добавлено: Пт дек 23, 2011 08:07 |
|
|
|
|
|
Заголовок сообщения: |
|
|
|
mOleg писал(а): be_nt_all писал(а): код для gcc генерировать ещё проще (хотя у llvm оптимизатор, судя по всему, лучше). Опять же gcc - это самый что ни на есть мейнстрим, а llvm и, тем более, cacao vm - ещё нет. особой разницы нет, придется с собой таскать еще один компилятор. это огромный минус.
Stacker Forth-подобный язык в LLVM
P.S. Есть и компилятор stkrc для генерации байт кода.
[quote="mOleg"][quote="be_nt_all"]код для gcc генерировать ещё проще (хотя у llvm оптимизатор, судя по всему, лучше). Опять же gcc - это самый что ни на есть мейнстрим, а llvm и, тем более, cacao vm - ещё нет.[/quote] особой разницы нет, придется с собой таскать еще один компилятор. это огромный минус.[/quote]
[url=http://llvm.org/releases/1.1/docs/Stacker.html]Stacker Forth-подобный язык в LLVM[/url]
P.S. Есть и компилятор stkrc для генерации байт кода.
|
|
|
|
Добавлено: Пт фев 19, 2010 20:22 |
|
|
|
|
|
Заголовок сообщения: |
|
|
|
be_nt_all писал(а): Вон Михаил свой оптимизатор таки забросил.
В какой-то мере. Руки не доходят. Я продвину оптимизатор если появится
критический по быстродействию фрагмент кода. Быстродействие моих программ
меня устраивает. Если кому надо, предъявляйте фрагменты кодов.
Если кто самостоятельно захочет добавить правило, пусть задает вопросы.
Что касается предлагаемого метода. Здесь завязана оптимизация на компиляцию.
Что черевато несовместимостью т.к. Форт предоставляет программисту вмешиваться
в процесс компиляции. Оптимизация при этом явно ограничена. Вообще не
вижу преимущества над моим методом.
[quote="be_nt_all"]Вон Михаил свой оптимизатор таки забросил.[/quote]
В какой-то мере. Руки не доходят. Я продвину оптимизатор если появится
критический по быстродействию фрагмент кода. Быстродействие моих программ
меня устраивает. Если кому надо, предъявляйте фрагменты кодов.
Если кто самостоятельно захочет добавить правило, пусть задает вопросы.
Что касается предлагаемого метода. Здесь завязана оптимизация на компиляцию.
Что черевато несовместимостью т.к. Форт предоставляет программисту вмешиваться
в процесс компиляции. Оптимизация при этом явно ограничена. Вообще не
вижу преимущества над моим методом.
|
|
|
|
Добавлено: Пт янв 29, 2010 17:15 |
|
|
|
|
|
Заголовок сообщения: |
|
|
|
be_nt_all писал(а): И кто-то должен всё это доводить, доводить и доводить... Пока всё это не доведёт его. Вон Михаил свой оптимизатор таки забросил. Процедуры конкретных доводок просты: берете и делаете(если надо). Никому, в том числе и Михаилу уже не сильно надо. Уже и так все быстро, все основные моменты уже выбраны. А если что-то на практике встретится медленное можно и ускорить по случаю и очень оперативно. Так сказать оптимизация по необходимости. Возьмем форт-систему от MPE (VFX). Там уже сделано нечто подобное тому, что предлагал Ертль. И что она на порядок быстрее СПФ? Таки нет же. Только чуть. be_nt_all писал(а): Любая оптимизирующая кодогенерация (если не использовать чужой промежуточный транслятор, где доводкой занимается кто то другой) включает такой элемент, но peephole из него одного и состоит.
А вот это совсем плохо - значит в оптимизаторе надо вручную подключать веер peеphole-разрешений кода.
[quote="be_nt_all"]И кто-то должен всё это доводить, доводить и доводить... Пока всё это не доведёт его. Вон Михаил свой оптимизатор таки забросил.[/quote] Процедуры конкретных доводок просты: берете и делаете(если надо). Никому, в том числе и Михаилу уже не сильно надо. Уже и так все быстро, все основные моменты уже выбраны. А если что-то на практике встретится медленное можно и ускорить по случаю и очень оперативно. Так сказать оптимизация по необходимости. Возьмем форт-систему от MPE (VFX). Там уже сделано нечто подобное тому, что предлагал Ертль. И что она на порядок быстрее СПФ? Таки нет же. Только чуть. [quote="be_nt_all"]Любая оптимизирующая кодогенерация (если не использовать чужой промежуточный транслятор, где доводкой занимается кто то другой) включает такой элемент, но peephole из него одного и состоит. [/quote]
А вот это совсем плохо - значит в оптимизаторе надо вручную подключать веер peеphole-разрешений кода.
|
|
|
|
Добавлено: Пт янв 29, 2010 17:04 |
|
|
|
|
|
Заголовок сообщения: |
|
|
|
chess писал(а): Оптимальность тут обеспечивается не единым алгоритмом оптимизации, а набором частных подстановок, каждая из которых доведена до ума вручную с учетом всех возможностей целевого кода. И кто-то должен всё это доводить, доводить и доводить... Пока всё это не доведёт его. Вон Михаил свой оптимизатор таки забросил. Любая оптимизирующая кодогенерация (если не использовать чужой промежуточный транслятор, где доводкой занимается кто то другой) включает такой элемент, но peephole из него одного и состоит. chess писал(а): В Форте тоже можно хорошо задействовать(если понадобится).
Или определением набора векторных слов, или через оптимизацию. Второй способ ничем, по сути, не отличается от того, что в C/Fortran.
[quote="chess"]Оптимальность тут обеспечивается не единым алгоритмом оптимизации, а набором частных подстановок, каждая из которых доведена до ума вручную с учетом всех возможностей целевого кода. [/quote]
И кто-то должен всё это доводить, доводить и доводить... Пока всё это не доведёт его. Вон Михаил свой оптимизатор таки забросил. Любая оптимизирующая кодогенерация (если не использовать чужой промежуточный транслятор, где доводкой занимается кто то другой) включает такой элемент, но peephole из него одного и состоит.
[quote="chess"]В Форте тоже можно хорошо задействовать(если понадобится).[/quote]
Или определением набора векторных слов, или через оптимизацию. Второй способ ничем, по сути, не отличается от того, что в C/Fortran.
|
|
|
|
Добавлено: Пт янв 29, 2010 15:37 |
|
|
|
|
|
Заголовок сообщения: |
|
|
|
be_nt_all писал(а): upd. Имхо, как раз таки peephole (щелевая) оптимизация работает с кодом целевой машины. Cуть peephole оптимизации не в том, что она работает с целевым кодом, а в том, как она с ним работает. Грубо говоря это простая замена определенных опознанных кусков кода на другие, реально оптимальные куски для данной целевой машины. Оптимальность тут обеспечивается не единым алгоритмом оптимизации, а набором частных подстановок, каждая из которых доведена до ума вручную с учетом всех возможностей целевого кода. be_nt_all писал(а): А так, SSE очень хорошо задействовать в языках вроде J и K.
В Форте тоже можно хорошо задействовать(если понадобится).
[quote="be_nt_all"]upd. Имхо, как раз таки peephole (щелевая) оптимизация работает с кодом целевой машины. [/quote] Cуть peephole оптимизации не в том, что она работает с целевым кодом, а в том, как она с ним работает. Грубо говоря это простая замена определенных опознанных кусков кода на другие, реально оптимальные куски для данной целевой машины. Оптимальность тут обеспечивается не единым алгоритмом оптимизации, а набором частных подстановок, каждая из которых доведена до ума вручную с учетом всех возможностей целевого кода.
[quote="be_nt_all"]А так, SSE очень хорошо задействовать в языках вроде J и K.[/quote]
В Форте тоже можно хорошо задействовать(если понадобится).
|
|
|
|
Добавлено: Чт янв 28, 2010 11:06 |
|
|
|
|
|
Заголовок сообщения: |
|
|
|
dynamic-wind писал(а): это ж freeforth ;;; . almost SWAP-free thanks to compile-time renaming of the two registers ;;; caching the top two DATAstack cells
замечательно!
[quote="dynamic-wind"]это ж freeforth ;;; . almost SWAP-free thanks to compile-time renaming of the two registers ;;; caching the top two DATAstack cells[/quote]
замечательно! :D
|
|
|
|
Добавлено: Ср янв 27, 2010 21:19 |
|
|
|
|
|
Заголовок сообщения: |
|
|
|
mOleg писал(а): насчет оптимизаций. Появилась еще идея о возможности использования практики register renaming в достаточно простой форме.
собственно есть возможность кэширования вершины стека данных в двух (а может и более) регистрах процессора. Однако, лобовой подход тут не работает - при любом изменении глубины стека данных придется перегружать все используемые регистры и весь выигрыш обернется потерями, поэтому СПФ кэширует не два значения с вершины стека данных, а один в EAX.
возможно, кто-то уже делал подобное.?
это ж freeforth
;;; . almost SWAP-free thanks to compile-time renaming of the two registers
;;; caching the top two DATAstack cells
[quote="mOleg"]насчет оптимизаций. Появилась еще идея о возможности использования практики register renaming в достаточно простой форме.
собственно есть возможность кэширования вершины стека данных в двух (а может и более) регистрах процессора. Однако, лобовой подход тут не работает - при любом изменении глубины стека данных придется перегружать все используемые регистры и весь выигрыш обернется потерями, поэтому СПФ кэширует не два значения с вершины стека данных, а один в EAX.
возможно, кто-то уже делал подобное.?[/quote]
это ж freeforth
;;; . almost SWAP-free thanks to compile-time renaming of the two registers
;;; caching the top two DATAstack cells
|
|
|
|
Добавлено: Ср янв 27, 2010 21:17 |
|
|
|
|
|
Заголовок сообщения: |
|
|
|
Ну и тогда уж, до кучи. Вот мы сейчас смотрим на LLVM с целью написания back-endа для процессорного ядра QuarkR. Он предполагается к изготовлению на "Ангстреме" по технологии 0,13 мкм, работать должно на 200 МГц (собственно, дизайн-центр имеет неплохие контакты в ЮВА, и "Ангстрем" - не единственная доступная foundry). В процессоре 32 бита и 32 симметричных регистра, трехадресные и стековые команды выполняются одновременно, без какого-либо переключения режимов (при старте указатель стека стоит на R31, так что к нему можно получить доступ и стековыми, и не-стековыми командами). Таким образом, вопрос об оптимизации работы со стеком не стоит - Форт поддерживается аппаратно, но и Си ляжет достаточно неплохо. Я отнюдь не призываю "пристроиться в хвост колонны", но вот вам пример российского продукта, под который пока нет средств разработки. Вот табличка с системой команд, можно заметить, что правила описания back-end-а довольно-таки регулярны.
Ну и тогда уж, до кучи. Вот мы сейчас смотрим на LLVM с целью написания back-endа для процессорного ядра QuarkR. Он предполагается к изготовлению на "Ангстреме" по технологии 0,13 мкм, работать должно на 200 МГц (собственно, дизайн-центр имеет неплохие контакты в ЮВА, и "Ангстрем" - не единственная доступная foundry). В процессоре 32 бита и 32 симметричных регистра, трехадресные и стековые команды выполняются одновременно, без какого-либо переключения режимов (при старте указатель стека стоит на R31, так что к нему можно получить доступ и стековыми, и не-стековыми командами). Таким образом, вопрос об оптимизации работы со стеком не стоит - Форт поддерживается аппаратно, но и Си ляжет достаточно неплохо. Я отнюдь не призываю "пристроиться в хвост колонны", но вот вам пример российского продукта, под который пока нет средств разработки. Вот табличка с системой команд, можно заметить, что правила описания back-end-а довольно-таки регулярны.
[img]http://www.msyst.ru/opcodes.jpg[/img]
|
|
|
|
Добавлено: Ср янв 27, 2010 21:13 |
|
|
|
|
|
Заголовок сообщения: |
|
|
|
Могу привести в качестве примера один use case по кварку. Преимущественный способ его использования - последовательные Evaluate строк, подаваемых модулем, к которому кварк подключен как библиотека. Модуль, разумеется, может захотеть посмотреть на состояние стека после выполнения некоторых действий. Если при этом вершина будет лежать в регистре, это обернется определенными сложностями - вершину стека, и остальной стек придется смотреть по-разному.
Могу привести в качестве примера один use case по кварку. Преимущественный способ его использования - последовательные Evaluate строк, подаваемых модулем, к которому кварк подключен как библиотека. Модуль, разумеется, может захотеть посмотреть на состояние стека после выполнения некоторых действий. Если при этом вершина будет лежать в регистре, это обернется определенными сложностями - вершину стека, и остальной стек придется смотреть по-разному.
|
|
|
|
Добавлено: Ср янв 27, 2010 21:06 |
|
|
|
|
|
Заголовок сообщения: |
|
|
|
chess писал(а): Там нет и вряд-ли будет даже что-то отдаленно похожее.
А что из себя их форт представляет?
[quote="chess"]Там нет и вряд-ли будет даже что-то отдаленно похожее.[/quote]
А что из себя их форт представляет?
|
|
|
|
Добавлено: Ср янв 27, 2010 20:46 |
|
|
|
|