Размещение объектов переменной длины с использованием множества стеков
Теперь рассмотрим возможность преодоления этих трудностей за счёт программного стека.
Представим себе цепочку вызовов: функция f1 вызывает вложенную функцию f2, которая,
в свою очередь, вызывает вложенную f3 и т.д.
Для каждого уровня вложенности можно сделать свой программный стек.
Вызывающая функция записывает параметры для вызываемой в стек этой функции.
Вызванная функция использует свой стек по своему усмотрению: размещает там, к примеру, локальные объекты.
Результат своей работы вызванная программа записывает не в свой стек, а в стек той функции, которая её вызвала.
Схематически это можно изобразить так (для простоты опустим пока что вопросы хранения адреса возврата и значения регистров;
но к этому ещё вернёмся):
Если в программе допустимы вызовы функций 256 уровней вложенности, то в памяти надо выделить 256 стеков.
Но разбить память на большое количество кусков — это не самая хорошая идея. Можно ли обойтись меньшим числом?
Допустим, двумя стеками, потому что недостаточность одного стека мы только что рассмотрели.
Читаем далее следующую статью:
Размещение объектов переменной длины с использованием двух стеков.
Почитайте ещё:
Опубликовано: 2014.07.27, последняя правка: 2018.10.29 16:02
Отзывы
✅ 2019/03/20 08:32, ВежливыйЛис #0
"резервировать память в стеке той функции, которая является «конечным потребителем».", — пишете вы в одном месте. А тут говорите, что стеки надо делать по количеству УРОВНЕЙ вызовов. Вы там как-нибудь определитесь уже — либо важны уровни, либо функции, либо их картезианское произведение.✅ 2019/03/21 16:55, Автор сайта #1
Здесь рассматривается экстремальный вариант, который хотелось рассмотреть с точки зрения теории: каждому новому вызову функции предоставляется свой стек. Т.е. это не предложение, а умозрительный эксперимент.
"резервировать память в стеке той функции, которая является «конечным потребителем»." — этого делать не надо, поскольку лучшее устройство функции — это когда она является «чёрным ящиком» и ничего не знает о своём окружении. Соответственно, она не должна знать, на какой уровень вложенности возвращать результат. Если в цепочке вызовов f0, f1, f2, f3 функция f3 должна вернуть результат напрямую в f0, то пусть она сделает это напрямую: f0() { f3(x) }. f1 и f2 – либо лишние, либо производящие побочные эффекты. Во втором случае можно переделать логику/последовательность работы этих функций.✅ 2019/03/22 11:12, ВежливыйЛис #2
Во втором случае можно переделать логику/последовательность работы этих функций. Сомнительно, что это можно сделать компилятором. А жизнь она разная.
Поддерживаю, в общем, Уткина. ЧТО Вы предлагаете (два стека) – это понятно. Ваша мысль про стек vs malloc тоже понятна. Но в сравнении всего Вашего подхода со стандартными вариантами сборки мусора (реалтаймовый Metronom, который изучают в западных университетах), не ясно, в чём преимущество. К тому же и гарантий реалтаймовости Вы не даёте.✅ 2019/03/22 23:05, Автор сайта #3
Сомнительно, что это можно сделать компилятором. Конечно, это работа программиста.стек vs malloc Что один стек, что два стека — они при занятии/освобождении памяти используют дисциплину LIFO: «последний пришёл — первый вышел». Просто из-за несовершенства языков, даже имея дисциплину LIFO, всё равно используют кучу. Просто потому, что языки не умеют возвращать значения переменной длины в стек вызывавшей функции. И не будут уметь, потому что единственный стек для этого не подходит. Тогда традиционные языки в этом случае используют кучу.
Противопоставлять стеки и кучу не стоит. Стеки не работают при дисциплине занятии/освобождении памяти, отличной от LIFO. У каждой модели — своя роль. Двухстековая модель использования памяти заполняет промежуточную нишу между обычной стековой моделью и кучей.не ясно, в чём преимущество Преимущество в 1) скорости занятия/освобождения памяти, 2) надёжности (я цитировал Л.В. Городнюю, наверное, читали), 3) в размере кода (посмотрите различные исходники malloc, free, new, delete и сравните с двумя машинными командами для занятия памяти и 0 команд для освобождения).К тому же и гарантий реалтаймовости Вы не даёте. Время занятия/освобождения памяти командами «CALL», «RET», «PUSH» и «POP» константно. Следовательно, в системах реального времени стек гарантирует фиксированное время исполнения кода.
Даю гарантии. Если Вы — Мефистофель, готов подписать с Вами договор о гарантиях. Подпись поставлю кровью. Приходите в полночь, времени осталось немного.✅ 2019/03/23 14:19, ВежливыйЛис #4
я цитировал Л.В. Городнюю, наверное, читали У неё много книжек, про функциональное программирование, про параллельное. Какую именно Вы процитировали?✅ 2019/03/23 19:01, Автор сайта #5
Я с её позволения цитировал личную переписку. Хотя, бывало, она и публично комментировала. Добавить свой отзыв
Написать автору можно на электронную почту mail(аt)compiler.su
|