Forth http://www.fforum.winglion.ru/ |
|
локальные фреймы данных http://www.fforum.winglion.ru/viewtopic.php?f=25&t=2354 |
Страница 1 из 3 |
Автор: | mOleg [ Вс дек 20, 2009 22:42 ] |
Заголовок сообщения: | локальные фреймы данных |
в Форте существует слово PICK , позволяющее положить на вершину стека данных копию значения, лежащего глубоко под вершиной стека. Практика его использования показала, что механизм неудобный, постоянное перемещение вершины указателя стека данных приводит к необходимости постоянного "пересчета" местоположения данных, а получаемые алгоритмы очень запутаны и практически не модифицируемы. В итоге, использование слова PICK стало неким нехорошим правилом. В результате в Форте сложилась ситуация, когда работать можно только с тремя - четырьмя числами на вершине стека данных, что с одной стороны не плохо, так как заставляет (принуждает) писать короткие определения, а с другой стороны усложняет работу программиста на алгоритмах, работающих с большим количеством данных. Для примера можно взять какую-нибудь форумулу: y = (a+b)*(b+c)*(a+c) видно, что каждый из параметров используется дважды. Предположим, что числа лежат на стеке данных ( a b c --> y ), код будет выглядеть следующим образом(без использования PICK): : f ( a b c --> y ) похожим образом с использованием PICK : f ( a b c --> y ) что выглядит немногим лучше и всеравно требует перемещения мещающих данных на стек возвратов. впрочем, без этого можно обойтись, но тогда получится еще длиннее. Решений у проблемы было найдено несколько. Одним из стандартных решений стало использование локальных переменных: : f { a b c } что выглядит значительно лучше. Однако локальные переменные работают не самым лучшим образом. В первую очередь, локальные данные хранятся на вершине стека данных, а это значит, что действительны только внутри одного определения. Во-вторую очередь, каждый используемый локальный параметр переносится на стек возвратов, что отнимает время. Кроме того, сами по себе локальные переменные реализуются достаточно сложным образом. Ну и использование стека возвратов тоже не слишком приятно. Локальные переменные в таком виде выглядят несколько инородными и черезмерно сложными в реализации. Другие решения конечно же есть. Например, стековые фреймы Хищника. Идея здравая (хотя признаюсь, сразу я ее не понял, каюсь). А действительно, зачем пермещать данные на стек возвратов? зачем лишние движения, когда можно несколько модифицировать работу PICK убрав известные существующие в нем проблемы! Для этого нужно, чтобы PICK работал не относительно подвижной вершины стека данных, а относительно какого-то другого перегружаемого указателя. То есть напрашивается примерно следующий код: USER-VALUE marker то есть, перед(или после) обявлением фрейма данных текущая вершина стека данных запоминается в специальном регистре, относительно которого можно получить адрес нужного нам параметра. Уже лучше, механизм проще, данные не перемещаются, сложная библиотека не нужна, и работать с параметрами можно внутри любого определения. НО! механизм нельзя использовать во вложениях, то есть нереентерабелен, что несомненно плохо. Хищник решил раз и на всегда эту проблему с помощью введения не переменной marker а отдельного стека, правда пришлось добавить слово, выталкивающее ненужный маркер со стека. Но еще один стек заводить не хочется! Да и возможность использовать механизм фреймов данных во вложенных определениях (то есть не на одном уровне) несколько сомнительна и черевата отчаянными "зевами". Значит можно попробовать обойтись без дополнительного стека данных: USER marker Вот такие мысли. P.S. да, стоит добавить, что введение дополнительного стека плохо еще и тем, что отражается на работе механизма CATHC THROW , то есть работы с исключениями. А именно: необходимо модифицировать эти слова таким образом, чтобы отслеживалась актуальная глубина стек указателей фреймов на момент каждого отката. Поэтому использование стека возвратов видится более подходящим для сохранения старых значений. |
Автор: | вопрос [ Вс дек 20, 2009 22:57 ] |
Заголовок сообщения: | |
Цитата: USER-VALUE marker явно что-то не то из стандартa Цитата: 6.2.1850 MARKER CORE EXT
( "<spaces>name" -- ) Skip leading space delimiters. Parse name delimited by a space. Create a definition for name with the execution semantics defined below. name Execution: ( -- ) Restore all dictionary allocation and search order pointers to the state they had just prior to the definition of name. Remove the definition of name and all subsequent definitions. Restoration of any structures still existing that could refer to deleted definitions or deallocated data space is not necessarily provided. No other contextual information such as numeric base is affected. See: 3.4.1 Parsing, 15.6.2.1580 FORGET. |
Автор: | mOleg [ Вс дек 20, 2009 23:10 ] |
Заголовок сообщения: | |
вопрос писал(а): явно что-то не то
из стандартa Цитата:6.2.1850 MARKER на стандарт забей, он тут не причем. Форт различает регистр, поэтому MARKER <> marker |
Автор: | dynamic-wind [ Вс дек 20, 2009 23:38 ] |
Заголовок сообщения: | |
етить! фортерами изобретен frame pointer! pin: push ebp mov ebp,esp item: mov eax,[ebp+eax] sever: mov esp,ebp pop ebp |
Автор: | mOleg [ Вс дек 20, 2009 23:45 ] |
Заголовок сообщения: | |
dynamic-wind писал(а): етить! фортерами изобретен frame pointer!
проблема не придумать а органично вписать механизм. причем, сделать это ка к можно более эффективным образом что собственно, вы и проиллюстрировали в коде. хотя ассемблерный код будет чуточку посложнее. |
Автор: | Hishnik [ Вс дек 20, 2009 23:45 ] |
Заголовок сообщения: | |
frame pointer за ненадобностью обычно не реализуется. Но что он есть, фортер не может не знать. |
Автор: | mOleg [ Пн дек 21, 2009 00:20 ] |
Заголовок сообщения: | |
dynamic-wind писал(а): етить! фортерами изобретен frame pointer!
да, забыл сказать, что по сути такая работа с данными чужда Форту. Стек не всегда доступен на чтение в глубину, и фреймы данных ни на одном из стеков просто не получится (и форт без этого механизма прекрасно обходится). Данный вопрос больше актуален для оптимизации работы с данными на регистровых архитектурах. |
Автор: | mOleg [ Пн дек 21, 2009 23:28 ] |
Заголовок сообщения: | |
да, стоит добавить, что введение дополнительного стека плохо еще и тем, что отражается на работе механизма CATHC THROW , то есть работы с исключениями. А именно: необходимо модифицировать эти слова таким образом, чтобы отслеживалась актуальная глубина стек указателей фреймов на момент каждого отката. Поэтому использование стека возвратов видится более подходящим для сохранения старых значений. |
Автор: | mOleg [ Ср дек 23, 2009 23:01 ] |
Заголовок сообщения: | |
так, возник вопрос, который не могу решить, а именно, в какую сторону надо отсчитывать значения для item вариантов-то всего два: от места метки в глубину, то есть, предполагается, что данные уже лежат на стеке, от места метки вверх, то есть предполагается, что данных еще нет. |
Автор: | вопрос [ Чт дек 24, 2009 00:45 ] |
Заголовок сообщения: | |
исходить из здравого смысла - обе |
Автор: | Hishnik [ Чт дек 24, 2009 15:56 ] |
Заголовок сообщения: | |
mOleg писал(а): так, возник вопрос, который не могу решить, а именно, в какую сторону надо отсчитывать значения для item
вариантов-то всего два: от места метки в глубину, то есть, предполагается, что данные уже лежат на стеке, от места метки вверх, то есть предполагается, что данных еще нет. А все сведется к тому, какой знак будут иметь индексы. |
Автор: | mOleg [ Чт дек 24, 2009 20:07 ] |
Заголовок сообщения: | |
Хищник писал(а): А все сведется к тому, какой знак будут иметь индексы.
угу, и запрещать ли отрицательные смещения. |
Автор: | mOleg [ Сб мар 17, 2012 19:31 ] |
Заголовок сообщения: | Re: локальные фреймы данных |
продолжаемс source file: loc.fts приведен низкоуровневый кусок поддержки локальных переменных на стеке данных, незначительно переработан вариант от Harry. |
Автор: | gudleifr [ Сб мар 17, 2012 20:19 ] |
Заголовок сообщения: | Re: локальные фреймы данных |
когда я был молодой и глупый, я тоже писал подобную хрень: Код: Screen 9 Но практика показала, что двух проектов, для которых подобная хрень будет выглядеть одинаково, нет. Например, сейчас, когда я гружу в стек параметры для Win-подпрограмм (включая структуры), ARENE используется совсем для другого - обрамления Win-вызова:0 N.( Стековые списки ARENE: связь+данные) 1 VARIABLE ARENE 2 \ New: Stack <= Arene; Arene <- Stack; Stack <= N(0); 3 : ARENE-NEW ( N->SA,N*0) SP@ ARENE @ >R ARENE ! R> SWAP 4 0 DO 0 LOOP ; 5 \ Free: Stack <- Arene; Arene <= Stack; 6 : ARENE-FREE ( SA,...->) ARENE @ SP! ARENE ! ; 7 : (ARENE) ( N->SA) 2* ARENE @ + ; 8 : ARENE@ ( N->W) (ARENE) S@ ; : ARENE! ( W,N->) (ARENE) S! ; 9 \ Link: Stack <= Arene[N1]; Arene[N1] <- Stack; Stack <= N2(0); 10 : ARENE-LINK ( N1,N2->SA,N1*0) >R >R R@ ARENE@ SP@ R> ARENE! 11 R> 0 DO 0 LOOP ; 12 \ List: For(; SA; CFA(SA), SA <- Stack[SA-2]); 13 : ARENE-LIST ( CFA,SA->) BEGIN ?DUP WHILE 2DUP 14 S@ SWAP EXECUTE ( W->) 2- S@ REPEAT DROP ; 15 Ok Код: \ ФОРМИРОВАНИЕ КАДРА СТЕКА Я, конечно, за то, что бы тут все хвастались наработками, но в случае локальных переменных требуется не "самая быстрая и универсальная" реализация, а взвешенное решения вотроса на@#$ они @#$ нам @#$cь? Это что, единственная известная нам модель временного хранения результатов вычислений?
CODE SP@ ( -- wa) B PUSHR, /DW MOV, B SP [RG] NEXT, END-CODE CODE SP! ( ..., wa -- ) /DW MOV, SP B [RG] B POPR, NEXT, END-CODE CODE ARENE ( R: -- wa) ( Т.Е. SP@ >R) B PUSHR, /WO MOV, SP BP [8] 0 C, /SW ADDD, BP [RG] 4 C, B POPR, NEXT, END-CODE CODE ARENE-DROP ( ... -- w; R: wa -- ) ( Т.Е. R> SP! ) /SW SUBD, BP [RG] 4 C, /DW MOV, SP BP [8] 0 C, B POPR, NEXT, END-CODE CODE ARENE-RET ( ..., w -- w; R: wa -- ) ( Т.Е. R> SWAP >R SP! R> ) /SW SUBD, BP [RG] 4 C, /DW MOV, SP BP [8] 0 C, A POPR, NEXT, END-CODE |
Автор: | mOleg [ Вс мар 18, 2012 08:03 ] |
Заголовок сообщения: | Re: локальные фреймы данных |
gudleifr писал(а): но в случае локальных переменных требуется не "самая быстрая и универсальная" реализация, а взвешенное решения вотроса да пожалуйста, просто альтернатива с локальными данными на стеке данных (а не возвратов, как в локалсах стандартных) удобнее, быстрее и как бы фортовее, т.е. логичнее. |
Страница 1 из 3 | Часовой пояс: UTC + 3 часа [ Летнее время ] |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |