Я работаю над этой проблемой прямо сейчас - то есть аналитическим вычислением размера стека. Очевидно, что это будет очень рекурсивный фрагмент кода, потому что вызов функции может иметь индексированный массив в качестве одного или нескольких аргументов, а один или несколько индексов массива могут включать вызовы функций !!
Однако пара реализаций позволяет немного облегчить сложность:
(1) При использовании компилятора языка высокого уровня указатель стека в конце выполнения каждого оператора / строки кода должен находиться в том же месте, что и в начале. (По крайней мере, это хорошее правило, которое следует соблюдать, иначе у вас будут проблемы!)
(2) Указатель стека после возврата из каждой функции или вызова подпрограммы должен быть таким же, как и до вызова. Следовательно, максимальный размер стека - это максимальный размер стека по всем операторам программы, достигнутый в каждом операторе. (По крайней мере, это хорошее правило, которое следует соблюдать, иначе у вас будут проблемы!)
Конечно, оператор может включать в себя рекурсивные проблемы, о которых я упоминал выше, но, по крайней мере, проблема поиска требований к максимальному размеру стека для всей программы затем сводится к нахождению требований к максимальному размеру стека для каждого оператора, а затем к выбору максимума из них.
Это не может быть выполнено до тех пор, пока все вызываемые функции также не будут скомпилированы. Поэтому я создаю файл для каждого скомпилированного модуля, в котором записывается количество размеров стека для каждого оператора (в основном пиковое значение перед каждым вызовом функции и значение непосредственно перед каждым вызовом функции (за исключением любых еще неизвестных добавлений к размеру стека, вызванных функцией call) и имена задействованных функций.Затем я ретроспективно обрабатываю эти файлы с помощью рекурсивной процедуры, как только все функции скомпилированы, чтобы определить пиковый размер стека.
К счастью, помимо рекурсивных подпрограмм, требования к максимально возможному размеру стека не зависят от потока программы, хотя в типичном потоке (который зависит от данных) этот максимально возможный размер стека может никогда не быть достигнут.
Пример: предположим, что функция 1 вызывает функцию 2, и поток программы обеих зависит от значения данных X. Предположим, что существует диапазон X, который заставляет функцию 1 выполнять свой худший оператор, который включает вызов функции 2, которая не выполняется. это утверждение наихудшего случая для того же диапазона X. Поскольку мы вычислили максимально возможный размер стека, используя наихудшие случаи одновременно для функции 1 и функции 2, мы могли переоценить размер стека. По крайней мере, мы ошиблись в большей степени.
Мне нравится давать подпрограммам прерывания свое собственное пространство стека в стеке ОС, если они нужны, чтобы они не добавляли к требованиям стека программ, кроме адреса возврата из прерывания.
person
cloggervic
schedule
07.08.2013