реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Как выбрать оптимальный размер стека?
zombi
сообщение Feb 24 2013, 09:37
Сообщение #1


Гуру
******

Группа: Свой
Сообщений: 2 076
Регистрация: 10-09-08
Пользователь №: 40 106



Нужно выделить область под стек.
Много - жалко памяти.
Мало ...
Посчитать все возможные прерывания и pushы я просто не в состоянии.
Пока способа лучше чем постоянный анализ указателя в самом частом и самом высокоприоритетном прерывании ни чего не придумал.
Может существуют еще какие либо методы выбора оптимального размера стека?
Go to the top of the page
 
+Quote Post
prottoss
сообщение Feb 24 2013, 10:34
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



1. Заполните стек каким либо "магическим" числом.
2. Запустите программу и постарайтесь прогнать ее на всех возможных вариантах.
3. Проанализируйте стек.

В итоге будете видеть, на какую максимальную глубину может быть заполнить стек.


--------------------
Go to the top of the page
 
+Quote Post
zombi
сообщение Feb 24 2013, 12:46
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 2 076
Регистрация: 10-09-08
Пользователь №: 40 106



Цитата(prottoss @ Feb 24 2013, 13:34) *
постарайтесь прогнать ее на всех возможных вариантах.

Вот со всеми вариантами то и проблема.
Уже сейчас это практически не реально.
А в дальнейшем ещё будут измения, добавления и т.д.
Go to the top of the page
 
+Quote Post
maksimp
сообщение Feb 24 2013, 17:19
Сообщение #4


Местный
***

Группа: Участник
Сообщений: 313
Регистрация: 2-07-11
Пользователь №: 66 023



Цитата(zombi @ Feb 24 2013, 12:37) *
Нужно выделить область под стек.
Много - жалко памяти.
Мало ...

Для чего нужна память? Ответ - для стека и для статических переменных. Использовать malloc на микроконтроллере не следует.
Отводите для стека много памяти. Если слишком много отвели, то не хватит места для статических переменных и компилятор должен выдать ошибку (не уверен, не проверял, проверьте).
Go to the top of the page
 
+Quote Post
zombi
сообщение Feb 24 2013, 19:13
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 2 076
Регистрация: 10-09-08
Пользователь №: 40 106



Цитата(maksimp @ Feb 24 2013, 21:19) *
и компилятор должен выдать ошибку (не уверен, не проверял, проверьте).

Ну avrasm так точно ругаться не будет biggrin.gif
Go to the top of the page
 
+Quote Post
Petka
сообщение Feb 25 2013, 06:03
Сообщение #6


Профессионал
*****

Группа: Свой
Сообщений: 1 453
Регистрация: 23-08-05
Пользователь №: 7 886



Цитата(zombi @ Feb 24 2013, 13:37) *
Нужно выделить область под стек.
Много - жалко памяти.
Мало ...
Посчитать все возможные прерывания и pushы я просто не в состоянии.
Пока способа лучше чем постоянный анализ указателя в самом частом и самом высокоприоритетном прерывании ни чего не придумал.
Может существуют еще какие либо методы выбора оптимального размера стека?

Используйте GCC. В нём куча растёт "вверх", а стек "вниз" с вершины памяти. Размер стека вообще указывать не надо.
Go to the top of the page
 
+Quote Post
Непомнящий Евген...
сообщение Feb 25 2013, 07:05
Сообщение #7


Знающий
****

Группа: Свой
Сообщений: 771
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153



Цитата(Petka @ Feb 25 2013, 10:03) *
Используйте GCC. В нём куча растёт "вверх", а стек "вниз" с вершины памяти. Размер стека вообще указывать не надо.


Плюсы не велики. Если стек переполнится - будут ровно те же проблемы sm.gif

Автору
1. (Для ИАРа) Выделяешь под стек максимально возможный объем - если вдруг не велезешь в память - будет ошибка линковки
2. На верх стека пишешь магическое число (для ИАРа - на оба стека), периодически проверяешь, если проблема - выдаешь ошибку, перезагружаешься
3. (Для ИАРа) в map-файле есть расчет размера стека. Правда он весьма примерный, так как ничего не знает про то, какие прерывания могут у тебя "вкладываться", а какие - нет.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Feb 25 2013, 08:25
Сообщение #8


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (Непомнящий Евгений @ Feb 25 2013, 09:05) *
Плюсы не велики. Если стек переполнится - будут ровно те же проблемы sm.gif
Если стек переполнится в этом случае - то никакое указание размера стека другими способами уже не поможет. Это будет означать, что память кончилась вся. Совсем.

QUOTE (Непомнящий Евгений @ Feb 25 2013, 09:05) *
1. (Для ИАРа) Выделяешь под стек максимально возможный объем - если вдруг не велезешь в память - будет ошибка линковки
Там два стека. И можно поступить тем же образом, что и в gcc - исправив скрипт линкера заставить размещать стеки с конца. Причем в самом конце разместить стек возвратов (RSTACK), размер которого можно приблизительно оценить прикинув количество уровней вложенности подпрограмм и дав запас, скажем, 10-20 байт, а следом, ближе к началу памяти, разместить стек данных (CSTACK), вершина которого может безболезненно расти за пределы выделенной под CSTACK память до тех пор, пока не налезет на другие данные, т.е. пока физически есть свободная память. Можно указать размер CSTACK равный 0 и забыть про это. А уж если начнутся проблемы с переполнением - оптимизировать алгоритмы.
Делается это использованием символа '#' вместо '=' в определении сегментов и размещением определения RSTACK перед CSTACK:
CODE
-Z(DATA)RSTACK+_..X_RSTACK_SIZE#60-45F
-Z(DATA)CSTACK+_..X_CSTACK_SIZE#60-45F

QUOTE (Непомнящий Евгений @ Feb 25 2013, 09:05) *
2. На верх стека пишешь магическое число (для ИАРа - на оба стека), периодически проверяешь, если проблема - выдаешь ошибку, перезагружаешься
Увы, тоже помогает не всегда. Функция может резервировать на стеке несколько байтов (например под буфер) и в процессе работы изменять не все из них. И по закону подлости магическое число попадает как раз на эти неизменные байты в конце массива, а функция работает с началом массива, уже за магическим числом.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
zombi
сообщение Feb 25 2013, 08:59
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 2 076
Регистрация: 10-09-08
Пользователь №: 40 106



Какие ИАРы какие GCC ? Я на ассемблере всё пишу.

Ясно одно: идеального метода нет.
Пока остановился на способе "научного тыка", выяснил максимально необходимый размер стека при максимально возможной (на сегодняшний день) загрузке и добавил ровно половину на всяк случай.
И в самом частом и самом высокоприоритетном прерывании оставил анализ указателя чтобы в случае чего остановить всё с рааадостным сообшением "stack overflow" biggrin.gif
Go to the top of the page
 
+Quote Post
Petka
сообщение Feb 25 2013, 09:22
Сообщение #10


Профессионал
*****

Группа: Свой
Сообщений: 1 453
Регистрация: 23-08-05
Пользователь №: 7 886



Цитата(zombi @ Feb 25 2013, 12:59) *
Какие ИАРы какие GCC ? Я на ассемблере всё пишу.
....

Если пишете на асме, то тем более можете стек растить "вниз".
Go to the top of the page
 
+Quote Post
Непомнящий Евген...
сообщение Feb 25 2013, 09:26
Сообщение #11


Знающий
****

Группа: Свой
Сообщений: 771
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153



Цитата(Сергей Борщ @ Feb 25 2013, 12:25) *
Увы, тоже помогает не всегда. Функция может резервировать на стеке несколько байтов (например под буфер) и в процессе работы изменять не все из них. И по закону подлости магическое число попадает как раз на эти неизменные байты в конце массива, а функция работает с началом массива, уже за магическим числом.


Я забил магическими числами весь стек, и сделал определение "свободного" места. Понятно, что это не слишком точно, но как оценка - вполне работает.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Feb 25 2013, 10:00
Сообщение #12


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (Непомнящий Евгений @ Feb 25 2013, 11:26) *
Понятно, что это не слишком точно, но как оценка - вполне работает.
Безусловно.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
prottoss
сообщение Feb 25 2013, 11:47
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Цитата(Непомнящий Евгений @ Feb 25 2013, 15:26) *
Я забил магическими числами весь стек
Еще есть способ забивать стек не константой а последовательностью. Т.е magic++. Это более помогает при том, о чем говорил Сергей Борщ


--------------------
Go to the top of the page
 
+Quote Post
kolobok0
сообщение Feb 25 2013, 15:21
Сообщение #14


практикующий тех. волшебник
*****

Группа: Участник
Сообщений: 1 190
Регистрация: 9-09-05
Пользователь №: 8 417



Цитата(zombi @ Feb 25 2013, 12:59) *
...на ассемблере всё...


тогда проблем вроде как и нет.
направления решений
1) резервация под существующий код.
2) контроль за аварийностью, при выходе стэка куда ему не положено.

резервация - методы следующие.
1) посмотреть "след" от использования стэка. методы написаны выше.
2) прикинуть мысленно глубину поллинга и(или) глубину прерываний. умножить на 1,5 или 2

контроль за аварийностью (как способ вовремя закричать, что _ВНИМАНИЕ_ ышо работаем но уже тогось!!!) лучше делать на "постоянно" используемых функциях. типа выделение памяти или в цикле главной логики, как контроль за общими ошибками. при этом достаточно выставлять признак "всё плохо со стэком" и далее его считывать по мере опроса "старшим братом" или при выводе в юай.
Go to the top of the page
 
+Quote Post
zombi
сообщение Feb 25 2013, 15:50
Сообщение #15


Гуру
******

Группа: Свой
Сообщений: 2 076
Регистрация: 10-09-08
Пользователь №: 40 106



Цитата(kolobok0 @ Feb 25 2013, 18:21) *
направления решений ...

Вот уже лет 20 как так и делаю.
Думал за это время кто что новое придумал.
Ан нет, всё по старому.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 05:57
Рейтинг@Mail.ru


Страница сгенерированна за 0.01498 секунд с 7
ELECTRONIX ©2004-2016