Forth и другие саморасширяющиеся системы программирования Locations of visitors to this page
Текущее время: Сб июл 02, 2022 06:05

...
Google Search
Forth-FAQ Spy Grafic

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




Начать новую тему Ответить на тему  [ Сообщений: 39 ]  На страницу Пред.  1, 2, 3
Автор Сообщение
 Заголовок сообщения:
СообщениеДобавлено: Чт янв 04, 2007 13:07 
Не в сети

Зарегистрирован: Чт май 04, 2006 18:18
Сообщения: 456
Благодарил (а): 0 раз.
Поблагодарили: 1 раз.
WingLion писал(а):
yGREK писал(а):
тиотимолиновая батарея

ашоэта? :shuffle;

Это к Азимову ;)

_________________
http://forth.org.ru/~ygrek


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Чт янв 04, 2007 14:40 
Не в сети
Administrator
Administrator
Аватара пользователя

Зарегистрирован: Вт май 02, 2006 13:19
Сообщения: 3565
Откуда: St.Petersburg
Благодарил (а): 4 раз.
Поблагодарили: 72 раз.
oх... "уж послала так послала!" (с)...

_________________
С уважением, WingLion
Forth-CPU . RuF09WE
Мой Форт
Отсутствие бана это не заслуга юзера, а недоработка модератора (с)


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Пн янв 08, 2007 13:43 
Не в сети
Аватара пользователя

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

JIT в основном нужен не для повышения скорости компиляции, а для повышения быстродействия кода.
Для повышения скорости компиляции кода нужно исключить поиск имен в словарях во время компиляции.
Да и сами словари должны по идее переехать в редактор(в его буфер) форт-системы. Программист вводит новое слово в редакторе - ему автоматически присваивается очередной номер. При компиляции из таблицы
редактора по этому номеру и будет вытаскиваться код данного слова в виде Call на адрес или самого кода в виде
макроса(инлайн-вставки). Для каждого номера в таблице редактора можно записать последовательность номеров входящих в него слов на данном уровне вложенности(потребуется для формирования ядра поддержки из слов входящих в главное), флаг использования этого слова в главном слове программы и много другой информации(например количество использований данного слова в программе для автоматического выбора что компилировать для данного слова (Call - если использований слова много, или инлайн-вставку если кол-во использований равно одному). Компиляция в рантайме происходит без создания имен
слов - это прерогатива программиста. А для введения слов и ведения списка слов достаточно средств редактора.
Если же программист ошибочно введет слово с уже существующим именем - редактор например подсветкой покажет это.

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


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Пн янв 08, 2007 17:01 
Цитата:
Для повышения скорости компиляции кода нужно исключить поиск имен в словарях во время компиляции.
...

А это и есть сolorForth'овские preparsed sourсes, о которых вам говорят. Или другое название -- цикл ICE (interpretation-compilation-editing). То есть перенос некоторой части работы компилятора и на редактор тоже. Непривычно и по-стандарто-борчески, но крайне эффективно и показало жизнеспособность в оригинальной системе Мура.

Недавно чё-то вякал подобное по этому поводу в чате:

profiT1984 писал(а):
А вообще, я тут думаю, как разумный компромисс между скоростью генерации-компиляции-оптимизации и скоростью выполнения можно временно переходить в шитый код... И не просто в подпрограммный, отключением оптимизатора, а допустим, косвенный...
Так как выясняется что по скорости критичны оказаться могут обе фазы..
Или как другой но уже несколько оторванный от реальности вариант: использовать в генерации не EVALUATE , а что-то другое.. Допустим диалект colorForth. Он парсится, компилируется, и даже оптимизируется гораздо легче...


Вариант с colorForth'ом в принципе предпочтительнее, но это писать достаточно много, пусть даже и есть две работающие намётки: ~profit/lib/colorSP4th.f и ~profit/lib/loveall.f.

А теперь, вести с полей динамической генерации кода:

Есть вот такой лозунг: "No stinking loops". Лозунг хороший, и даже более того -- полезный. Первым на гильотину у меня взойдут циклы со счётчиком, то есть DO LOOP (и FOR NEXT , за компанию). Говорить что последовательный пробег от одного числового значения к другому значению используется часто -- ничего не сказать. Это и проход по ячейкам памяти, это и 1, 2, 3, 4, 5 , это по сути если и не альфа и омега, то пол-греческого алфавита -- точно. А меж тем вы-факторизи-ро-вы-ваются (э-э-э.. ну, вы поняли) циклы только bac4th-итераторами.

~profit/lib/bac4th-iterators.f -- вот там есть слово iterateBy . Вещь, казалось, бы незамысловатая, элементарная и низкоуровневая. Слово это берёт со стека начальное число, длину, и шаг и последовательно проходит всю длину от начала делая по шагу в каждой итерации:

Код:
REQUIRE iterateBy ~profit/lib/bac4th-iterators.f

\ Пример работы слова iterateBy ( start len step --> i \ i <-- i )
: r 1 10 1 iterateBy DUP . ;
\ вывод: 1 2 3 4 5 6 7 8 9 10
r


Вообще, для такой постоянно используемой элементарщины как 1, 2, 3, 4, 5 ; bac4th -- слегка жирно и неэкономно, хотя и очень концептуально и гибко. Чтобы ускорить это дело можно заиспользовать генерацию кода. Генерируем (в ходе исполнения, само собой) примерно такой кусочек кода (start, step и end вкомпилировываются в код во время генерации):

Код:
PRO
start
BEGIN
( i ) CONT ( i )
step +
DUP end > UNTIL
DROP


И пускаем его пастись EXECUTE'ом с передачей успехов этого сгенерированного итератора дальше. В результате экономим как память в виде ячеек R-стека, так и и процессорное время.

В качестве ещё несколько более хакового, но гораздо более быстрого варианта, можно использовать тот факт что этот сгенерированный цикл-итератор используется только один раз, и, соответственно, адрес для вызова успеха будет только один и не изменится:

Код:
PRO
start
BEGIN
( i ) [ success-xt COMPILE, ] ( i )
step +
DUP end > UNTIL
DROP


Тогда будет экономия и L-стека используемого в PRO ... CONT .

Несмотря на то что, по идее, эти циклы должны рвать всё и вся по скорости, на деле, в некоторых случаях, они оказываются даже медленнее своих статических братьев -- негенерируемых DO LOOP и BEGIN UNTIL. Почему? Тормоза вылезают в достаточно нетривиальной и слегка тяжёлой (каламбур, да) генерации кода которая основана на SPF-ном EVALUATE. Там тормозов даже несколько: разбор, поиск, оптимизатор. Не надо говорить, что там в принципе всё достаточно быстро: если попробовать погенерировать по паре миллионов замыканий, и пройтись profiler'ом, то это всё вылезет на поверхность. Ситуация существенно улучшается при включении хэш-поиска по словарям (~pinka/spf/quick-swl.f), и отключения оптимизатора (это не шутка), хотя бы на время генерации кода. Тем не менее, я пока так делать не хочу...

Как приемлемое решение в работу, рассматриваю выбор одного из нескольких вариантов iterateBy в зависимости от намечаемой продолжительности цикла, то есть если цикл коротенький, и генерация кода цикла-итератора займёт больше времени чем сама обработка цикла, то будет выбираться статический вариант, если цикл масштабен и выше только небо то генерация цикла-итератора становится копеечными вложениями, приносящими при обработке горы сэкономленного процессорного времени. Решение, очевидно принимается в ходе исполнения, в зависимости от полученных данных:

Код:
: iterateBy ( start len step --> i \ i <-- i ) PRO
2DUP 6 LSHIFT ( 2* 2* 2* 2* 2* 2* ) <
\ Решаем: если кол-во итераций в цикле будет меньше чем, скажем 64 (взято с потолка),
IF iterateBy2 CONT EXIT THEN
\ то циклуем статически,
   iterateBy4 CONT ;
\ иначе, если больше чем 64, -- то генерируем цикл и пускаем в нём


При этом эти внутренние пертурбации одного словечка iterateBy (порядка пяти-шести вариантов) внешне остаются незаметными для программ, так как все вариации iterateBy делают одно и то же -- проход по числовому ряду.

Coming soon on CVS...


Вернуться к началу
  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Вт фев 13, 2007 14:27 
В ходе использования периодически были глюки со структурами управления которые генерируются динамически. Конкретно это било по слову iterateBy3 которые для прохода по диапазону чисел генерировало цикл (подробнее см. выше).

Глюк проявлялся в том что попеременно вылезали сообщения то "Exception 87", то "J_ERR" (ygrek'у и его IRC-боту привет!), то ещё что-нибудь совсем несусветное.

Это было устранимо если переписать ?BRANCH и UNTIL на высоком уровне, но это бы перечеркнуло собственно цель для чего делались такие генерируемые циклы -- скорость.

И, покопавшись, потеряв ещё нескольк волос, теперь я имею показать разоблачение глюка и казнь его (по крайней мере, на моей стороне).

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

Не знаю, может ли или нужно ли анализировать такие случаи самому оптимизатору...


Вернуться к началу
  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Пт фев 23, 2007 17:17 
Мда. Даже непонятно, хорошо или плохо то что я сделал. С одной стороны -- удалось при компиляции кода обеспечить надёжное разбиение на куски маш. кода не полагаясь больше на увеличенный люфт. С другой стороны -- достигнуто это такими средствами, что самый смысл изначальной задачи как-то изрядно потускнел.

Чтобы перехватывать все попытки компиляции кода, "взламываем" DP: (dp-hook.f). Это уже само по себе хак. После выполнения этого файла становится возможным писать в переменную /DP-HOOK вектор процедуры которая будет выполняться при запуске компилирующих слов. Теперь мы получили контроль за компиляцией, так как каждое компилирующее в кодофайл слово постоянно и даже по нескольку раз запускает DP.

Теперь нужно только во время компиляции в виртуальные кодофайлы в перехватчике смотреть не зашло ли значение DP за границу, и если да, то создавать новый блок, компилировать на него безусловный переход и устанавливать DP на начало этого блока. И тут начинаются первые проблемы с оптимизатором и обходные манёвры. Во-первых, компиляция команд всегда идёт в несколько приёмов несколькими компилирующими командами, например:

Код:
: _COMPILE,  \ 94 CORE EXT
  ?SET
  SetOP
  0x0E8 C,              \ машинная команда CALL
  DP @ CELL+ - ,
  DP @ TO LAST-HERE
;


Перехватчик во время выполнения этого компилирующего слова выполнится несколько раз (в C, , в DP ). Само собой что первый байт маш. команды CALL в одном блоке, и оставшийся кусок -- в другом блоке, нам совершенно не нужны, поэтому делить на куски во время компиляции маш. команды нельзя. В определении того когда начинается маш. команда, а когда мы находимся в середине её, нам поможет служебная структура оптимизатора, которые он использует для того же самого. Конкретно, у оптимизатора есть группа переменных OP0, OP1, OP2 и т.д. в котором записаны адреса начал последних 8-и маш. команд (их кстати ставит слово SetOP). Поэтому делить на куски нам можно только если HERE равен OP0:

Код:
: VC-CHECK ( -- )       \ Обработчик компиляции
HERE OP0 @ <> IF EXIT THEN
HERE vc @ limit @ >  IF \ Проверка на выход за границы текущего блока кодофайла
... \ создание нового куска кода
;


Сирены и Сцилла преодолены, но дальше там сидит такая Харибда... Имя ей -- INLINE, ...

Бяка в том что слово INLINE, оказалось несовместимо со "скачущим" DP. Если мы компилируем слово состоящее из двух маш. команд op1 и op2, и если разрыв приходится аккурат между op1 и op2, то после работы INLINE, мы имеем такую грустную картину в виртуальном кодофайле:

Код:
op1
jmp <следующий кусок кода>
op2


Тогда как нужно было:

Код:
op1
jmp <следующий кусок кода>

...

следующий кусок кода:
op2


"Ну и что?.. Как будто это INLINE, часто применяется". Но, оно и в самом деле применяется не просто часто, а сплошь и рядом в SPF. Скажем, LIT, или циклы DO ... LOOP и т.д. И установка DIS-OPT/SET-OPT не оказывает на это слово никакого воздействия (что в общем-то только логично, компилирование макросов --
это другая, достаточно отличающаяся от оптимизатора задача).

Приходится писать ещё один мега-пупер-хакище, который окончательно подвешивает моё желание это внедрять в работу на тонюсенький волосок (не говоря уже о существенном увеличении времени компиляции):


Код:
: VC-CHECK ( -- )       \ Обработчик компиляции
HERE OP0 @ <> IF EXIT THEN
HERE vc @ limit @ >  IF \ Проверка на выход за границы текущего блока кодофайла
R0 @ RP@ DO I @ ['] _INLINE, ['] OPT_CLOSE WITHIN IF UNLOOP EXIT THEN CELL +LOOP
... \ создание нового куска кода
;


Правда, насколько я понимаю, оба хака можно устранить путём соответствующих изменений в ядро. Вот только нужны ли виртуальные кодофайлы настолько?..

Пока на CVS не заливаю.


Вернуться к началу
  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Пт фев 23, 2007 17:54 
Цитата:
оба хака можно устранить путём соответствующих изменений в ядро


Вызывать что-то типа CHECK-HERE перед каждой откладывающей команды?
По идее, слов таких в SPF немного: <code>COMPILE, LIT, 2LIT, SLIT, ?BRANCH, BRANCH,</code>
вначале каждого из них тогда надо вызвать CHECK-HERE ...
Непонятно, как лучше быть с "SLIT,"


Вернуться к началу
  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Сб фев 24, 2007 17:45 
Не в сети

Зарегистрирован: Ср май 03, 2006 11:27
Сообщения: 1394
Откуда: St.Petersburg
Благодарил (а): 2 раз.
Поблагодарили: 11 раз.
profiT писал(а):
Но, оно и в самом деле применяется не просто часто, а сплошь и рядом в SPF. Скажем, LIT, или циклы DO ... LOOP и т.д. И установка DIS-OPT/SET-OPT не оказывает на это слово никакого воздействия (что в общем-то только логично, компилирование макросов --
это другая, достаточно отличающаяся от оптимизатора задача).


Как я понял речь идет о компиляции временного фрагмента кода.
В этом случае не нужна ни оптимизация ни инляйн-подстановка.
За исключением слов типа LIT, или циклы DO ... LOOP , инляйн-подстановку можно
отключить обнулением переменной MM_SIZE. Слова типа LIT, или циклы DO ... LOOP
можно переопределить (можно, в некой библиотеке).


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Сб июн 09, 2007 10:08 
---


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

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


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

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


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

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