Как определить максимальное использование стека?

Предупреждение: Деление на ноль

Предупреждающее сообщение «Подразделение на ноль» является одним из наиболее часто задаваемых вопросов среди новых разработчиков PHP. Эта ошибка не вызовет исключения, поэтому некоторые разработчики будут иногда подавлять предупреждение, добавляя оператор подавления ошибок @ перед выражением. Например:

$value = @(2 / 0);

Но, как и при любом предупреждении, наилучшим подходом было бы отслеживать причину предупреждения и разрешать его. Причина предупреждения будет происходить из любого экземпляра, где вы пытаетесь разделить на 0, переменную, равную 0, или переменную, которая не была назначена (поскольку NULL == 0), потому что результат будет «неопределенным».

Чтобы исправить это предупреждение, вы должны переписать свое выражение, чтобы проверить, что значение не равно 0, если оно есть, сделать что-то еще. Если значение равно нулю, вы не должны делиться или изменять значение на 1, а затем делить так, что деление приводит к эквиваленту того, что он разделен только дополнительной переменной.

if ( $var1 == 0 ) { // check if var1 equals zero
    $var1 = 1; // var1 equaled zero so change var1 to equal one instead
    $var3 = ($var2 / $var1); // divide var1/var2 ie. 1/1
} else {
    $var3 = ($var2 / $var1); // if var1 does not equal zero, divide
}

Вопросы, относящиеся:

42
задан Judge Maygarden 13 February 2012 в 16:18
поделиться

3 ответа

Наиболее распространенный способ определить самое глубокое использование стека состоит в том, чтобы инициализировать стековую память с некоторым известным, но необычным значением, тогда периодически (или в конце большого тестового прогона) видят, где тот шаблон останавливается.

Это точно, как IDE IAR определяет сумму используемого стека.

30
ответ дан Michael Burr 26 November 2019 в 23:57
поделиться

Вы отметили свой вопрос со статическим анализом, но это - проблема, которую трудно решить посредством статического анализа. Использование стека зависит от профиля программы во время выполнения, особенно при использовании рекурсии или alloca. Учитывая, что это - встроенная платформа, я предполагаю, что также трудно выполнить что-то как ps или вершина и видеть, сколько стека Ваше приложение использует.

интересный подход должен использовать адрес текущего стекового фрейма для определения, сколько стека используется. Можно сделать это путем взятия адреса аргумента функции или локальной переменной. Сделайте это для основной функция, и для функций Вы думаете, используют большую часть стека. Различие скажет Вам сумму стека, которого требует Ваше приложение. Вот пример (принимающий обычный высокий-к-низкому рост стека).

char *stack_top, stack_bottom;

int
main(int argc, char *argv[])
{
    stack_top = (char *)&argc;
    // ...
    printf("Stack usage: %d\n", stack_top - stack_bottom);
}

void
deeply_nested_function(void)
{
    int a;
    stack_bottom = (char *)&a;
    // ...
}

, Если Ваш компилятор позволяет Вам определять пользовательский пролог функции (многие делают это для разрешения основанного на графике профилирования программы), можно даже принять меры, чтобы все функции назвали такой код измерения. Тогда Ваше измерение функционирует mecomes что-то как

void
stack_measurement_function(void)
{
    int a;
    stack_bottom = min(stack_bottom, (char *)&a);
    // ...
}

, я использовал подход, подобный тому, что я описал для генерации эти диаграммы .

22
ответ дан Diomidis Spinellis 26 November 2019 в 23:57
поделиться

С помощью хорошего инструмента статического анализа исходного кода вы можете создать граф вызовов для своего приложения. Учитывая это, а также оценки количества локальных переменных / временных файлов, созданных вашим компилятором, вы можете легко вычислить консервативную оценку потребности в стеке.

Под «хорошим» инструментом анализа я подразумеваю тот, который может читать все единицы компиляции. может определять прямые вызовы функций, может определять косвенные указатели в блоке компиляции, может вычислять консервативный анализ точек для всей системы, может строить граф вызовов с учетом анализа точек. Это исключает использование множества инструментов, поэтому можно встретить специальные методы, такие как «заполнить стек во время выполнения и посмотреть, что произойдет». Вам также нужны оценки требований стека, которые компилятор помещает в стек; многое из этого можно приблизительно оценить, просто зная, насколько велики потребности в хранилище для всех типов, что обычно довольно легко определить для программ на языке C. Наконец, вы должны верить, что ваше приложение не имеет рекурсивных вызовов или что инструмент имеет представление о глубочайшей рекурсии (вероятно, по вашим словам).

DMS Software Reengineering Toolkit удовлетворяет всем этим требованиям для C программы. См. http://www.semanticdesigns.com/Products/DMS/DMSToolkit.html Вам по-прежнему необходимо настроить его для вычисления потребности в стеке путем обхода графа вызовов и использования различных оценок размера.

Если вам нужен быстрый ответ, используйте трюк с заполнением стека. Если вам нужен ответ, который можно будет пересчитывать после каждого изменения исходного кода, вам понадобится подход статического анализа.

5
ответ дан 26 November 2019 в 23:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: