-
- Напоминаю классический способ, не зависящий от компилятора. При запуске прописать область стека каким-нибудь характерным кодом, после выполнения посмотреть, где этот код уцелел. - vmp(29.10.2013 22:05)
- ну дык так и делаем, и это ещё в телеметрию гоним вместе с позадачным уровнем загрузки проца. лепота - Mahagam(29.10.2013 22:50)
- Вариант - определяете глобальную переменную max_depth_stack_size. В коде функций (после call и push) сравниваете текущий указатель стека с max_depth_stack_size. При новом рекорде обновляете max_depth_stack_size. гоняете основной цикл 100500 раз. SS:ESP(31 знак., 29.10.2013 21:57, )
- И так повторять два десятка раз (по числу задач, каждая использует свой стек в вытесняющей операционке). Смеётесь или не понимаете, что такое многозадачная вытесняющая RTOS? - VVB(30.10.2013 09:33)
- Решение соответствует поставленной задаче - точно измерить реальный максимум потребления сегмента стека конкретного процесса - SS:ESP(30.10.2013 10:42, )
- Операционная система обязана Каждому процессу предоставить ИЗОЛИРОВАННЫЕ стек и сегменты данных. Даже прерывания могут быть организованы как ЗАДАЧА - т.е. аппаратное переключение контекста (сохранение регистров) и переключение указателя на СВОЙ Операционная система(192 знак., 30.10.2013 10:38, )
- вы понимаете, что потоки в контроллере практически всегда имеют сильные взаимосвязи по данным между собой. Mahagam(144 знак., 30.10.2013 11:05)
- Нужно измерить реальный расход под стек? Ну так измерьте его! - SS:ESP(30.10.2013 11:16, )
- Если рассмативать RTOS как переключалку задач, тогда конечно, легальных методов нет. А вообще, большинство сервисов для этого и предназначены - семафоры, флаги, очереди сообщений. Мютексом в конце концов можно доступ к расшаренной памяти обернуть. Alex B.(108 знак., 30.10.2013 11:11)
- if (current_stack_pointer<deepest_bottom){deepest_bottom=current_stack_pointer;} Всралась очипятка - SS:ESP(30.10.2013 11:27, )
- if (current_stack_pointer<deepest_bottom)(deepest_bottom=current_stack_pointer;) Где что должно аццки тормозить? - SS:ESP(30.10.2013 11:22, )
- Deepest bottom? Надо же было так обозвать :-))) - SciFi(30.10.2013 11:27)
- Я просто к тому, что у англоязычных могут возникнуть самые разнообразные ассоциации, и стек вряд ли будет среди них :-) Low limit получше будет. - SciFi(30.10.2013 13:57)
- Я бы на их месте подумал, что "low limit"=="нихт бабкен" :-) - SS:ESP(30.10.2013 14:05, )
- Ибо стек растёт вниз! Потому и "глубочайшее дно" - SS:ESP(30.10.2013 11:28, )
- В контроллерах проф. уроня -- растёт вверх. Вообще-то не в каждой задаче, а перед вызовом каждой функции (если в стеке свободно менее N -- создать новый стек и вызвать функцию в новом стеке, например). Тяжеловатый подход... - fk0(30.10.2013 11:33)
- Для "проф?"контроллеров всё наоборот - if (current_stack_pointer>highest_top){highest_top=current_stack_pointer;} - SS:ESP(30.10.2013 11:42, )
- Тяжеловатый? Эффективный! Сначала задать размер стека заведомо большим, затем измерить. Задать размер стека по реальному расходу + небольшой запас - SS:ESP(30.10.2013 11:40, )
- Вот небольшого запаса однажды и не хватит (не все варианты работы программы можно измерить). Поэтому игрища со стеком с точным измерением, вместо того, чтоб попросту домножить на Pi^2, мне кажутся сомнительным занятием. - fk0(30.10.2013 11:42)
- Или внутри функций проверять а не маловат ли запас? Может попросить операционную систему какой-нибудь malloc() - SS:ESP(30.10.2013 11:48, )
- Внутри вызванной функции, если маловат -- что делать? Только abort() и остаётся. Стек уже не переместишь (в нём locals и arguments). А в вызывающей функции вместо call вполне можно сделать перемену стека и call функции в новом стеке. - fk0(30.10.2013 12:26)
- abort() только в случае if(malloc(4096)==NULL){exit(1);} Тогда уж больше некуда. Соответственно или редизайн, или толще камень - SS:ESP(30.10.2013 14:02, )
- Не обязательно, хотя сложнее работать с аргументами. Сохранить текущий sp, попросить новый блок памяти, загрузить новый sp, юзать, перед выходом освободить блок, вернуть старый sp. - SS:ESP(30.10.2013 13:46, )
- Замечтельно. Но как в новом стеке получить доступ к аргументам и переменным функции в _старом_. И как быть, что теперь часть переменных у нас в новом стеке, а часть в старом. Невозможно! Только если это всё проделать в прологе функции и, fk0(486 знак., 30.10.2013 14:04)
- А разве в прототипе функции не указывается количество и тип аргументов ?-) Или функция должна угадать количество pop перед ret ?-) - SS:ESP(30.10.2013 14:20, )
- Для функций с переменным числом аргументов pop будет делать тот кто вызывал. Поэтому не указывается. В паскале обратный порядок передачи аргументов в функцию, поэтому у них вовсе нет таких функций и невозможно на паскале написать функцию Writeln fk0(31 знак., 30.10.2013 14:53)
- Метки и переходы запретить! Кто не согласен, того на костер! - Облез Паскаль(30.10.2013 22:04, )
- Не надо дублировать аргументы в новом стеке, нужно знать адресную арифметику конкретного компилятора. Не сложно, но заморочено Ж-( - SS:ESP(30.10.2013 14:20, )
- Конечно проверять размер остатка стека сразу в начале функции и адресовать аргументы через вспомогательный указатель - не айс - SS:ESP(30.10.2013 14:21, )
- Например для потоков использовать единственный аргумент - указатель на структуру с полным фаршем переменных и аргументов - SS:ESP(30.10.2013 14:22, )
- Это какой-то альтернативный компилятор не-C из альтернативной вселенной. Разговор ни о чём. - fk0(30.10.2013 14:54)
- Указатель, структура - более чем C. Один аргумент - не надо ничего копировать между стеками - SS:ESP(30.10.2013 15:02, )
- Это уже какой-то словесный понос. Вот практический пример: как быть в случае printf("hello world %u %u %u %u %u...", 1,2,3,4,5,6,....100500....) ? И один аргумент может передаваться в стеке: void f(...) и f(1) потом. Или если gcc -O0 - fk0(30.10.2013 15:07)
- Практический ответ для любого компилятора: резервируете где хотите область памяти для строки желаемого формата (хоть с китайским %s), также область памяти под массив указателей на переменные к печати. Ну сами переменные, я надеюсь это понятно. SS:ESP(161 знак., 30.10.2013 15:28, )
- Покажите где ранее я сказал, что ЛЮБОЙ функции достаточно единственного аргумента? - SS:ESP(30.10.2013 15:27, )
- Понятно. Тролля лучше не кормить. - fk0(30.10.2013 15:42)
- Реализация описанного - работа и ответственность программиста. Не компилятора - SS:ESP(30.10.2013 16:02, )
- Понятно. Тролля лучше не кормить. - fk0(30.10.2013 15:42)
- Это уже какой-то словесный понос. Вот практический пример: как быть в случае printf("hello world %u %u %u %u %u...", 1,2,3,4,5,6,....100500....) ? И один аргумент может передаваться в стеке: void f(...) и f(1) потом. Или если gcc -O0 - fk0(30.10.2013 15:07)
- Указатель, структура - более чем C. Один аргумент - не надо ничего копировать между стеками - SS:ESP(30.10.2013 15:02, )
- Это какой-то альтернативный компилятор не-C из альтернативной вселенной. Разговор ни о чём. - fk0(30.10.2013 14:54)
- Например для потоков использовать единственный аргумент - указатель на структуру с полным фаршем переменных и аргументов - SS:ESP(30.10.2013 14:22, )
- Конечно проверять размер остатка стека сразу в начале функции и адресовать аргументы через вспомогательный указатель - не айс - SS:ESP(30.10.2013 14:21, )
- Для функций с переменным числом аргументов pop будет делать тот кто вызывал. Поэтому не указывается. В паскале обратный порядок передачи аргументов в функцию, поэтому у них вовсе нет таких функций и невозможно на паскале написать функцию Writeln fk0(31 знак., 30.10.2013 14:53)
- А разве в прототипе функции не указывается количество и тип аргументов ?-) Или функция должна угадать количество pop перед ret ?-) - SS:ESP(30.10.2013 14:20, )
- Замечтельно. Но как в новом стеке получить доступ к аргументам и переменным функции в _старом_. И как быть, что теперь часть переменных у нас в новом стеке, а часть в старом. Невозможно! Только если это всё проделать в прологе функции и, fk0(486 знак., 30.10.2013 14:04)
- Внутри вызванной функции, если маловат -- что делать? Только abort() и остаётся. Стек уже не переместишь (в нём locals и arguments). А в вызывающей функции вместо call вполне можно сделать перемену стека и call функции в новом стеке. - fk0(30.10.2013 12:26)
- Если размер оперативной памяти стремится к бесконечности, можно умножить реальный расход на гугол :-) - SS:ESP(30.10.2013 11:47, )
- Или внутри функций проверять а не маловат ли запас? Может попросить операционную систему какой-нибудь malloc() - SS:ESP(30.10.2013 11:48, )
- Вот небольшого запаса однажды и не хватит (не все варианты работы программы можно измерить). Поэтому игрища со стеком с точным измерением, вместо того, чтоб попросту домножить на Pi^2, мне кажутся сомнительным занятием. - fk0(30.10.2013 11:42)
- В контроллерах проф. уроня -- растёт вверх. Вообще-то не в каждой задаче, а перед вызовом каждой функции (если в стеке свободно менее N -- создать новый стек и вызвать функцию в новом стеке, например). Тяжеловатый подход... - fk0(30.10.2013 11:33)
- Я просто к тому, что у англоязычных могут возникнуть самые разнообразные ассоциации, и стек вряд ли будет среди них :-) Low limit получше будет. - SciFi(30.10.2013 13:57)
- Deepest bottom? Надо же было так обозвать :-))) - SciFi(30.10.2013 11:27)
- Для этого предназначен MMU. Которого нет в большинстве МК для реального управления объектами. MPU частично позволит решить вопрос выхода задачи на дозволенный для неё стек, порты FreeRTOS используют эти фичи. - VVB(30.10.2013 10:51)
- Для этого в контроллерах проф. уровня есть регистр указывающий на максимальную глубину стека. При переходе -- исключение. Без всяких MMU. - fk0(30.10.2013 11:34)
- В ПИКах "аппаратный" стек из 8 слов. "640 килобайт хватит на всех" (c) Билли - SS:ESP(30.10.2013 11:53, )
- В пиках давно уже и стек нормальный и 14-шт WREG'ов. Жить стало лучше, жить стало веселее. - fk0(30.10.2013 12:29)
- Уж лучше 32 регистра r0-r31 и нормальный стек "искаропки"... Хотя пройденный этап. По сравнению с однотактным умножением 32x32 и прочими ништяками - SS:ESP(30.10.2013 13:50, )
- Не знаешь о современных пик-контроллерах -- не пиши ерунды. Не самый плохой 16-битный CPU, однозначно лучше во всех смыслах ваших любительских AVR'ов. - fk0(30.10.2013 14:09)
- Для меня PIC умер 10 лет назад. AVR уже тоже. Да здравствует сами знаете что :-) - SS:ESP(30.10.2013 14:26, )
- Карл Маркс? - Крок(30.10.2013 22:35)
- Боюсь, для меня ARM умер 5 лет назад. Да здравствует сами знаете что. Хотя, я бы посмотрел в сторону Renesas. Бегать с высунутым языком и повторять как мантру ARM-ARM-ARM... нужно было в ~декабре ~2005 года, когда появились первые дешёвые LPC с fk0(83 знак., 30.10.2013 14:56)
- Всё только начинается! Intel осознал свою ошибку 20 летней давности, таки лицензирует ядра у ARM и будет их выпускать. Читайте новости за сегодня - SS:ESP(30.10.2013 15:11, )
- Я не читаю жёлтых газет. - fk0(30.10.2013 15:17)
- Тогда ждите пресс-релизов от Intel, Altera, TSMC - SS:ESP(30.10.2013 15:38, )
- Я не читаю жёлтых газет. - fk0(30.10.2013 15:17)
- Всё только начинается! Intel осознал свою ошибку 20 летней давности, таки лицензирует ядра у ARM и будет их выпускать. Читайте новости за сегодня - SS:ESP(30.10.2013 15:11, )
- Для меня PIC умер 10 лет назад. AVR уже тоже. Да здравствует сами знаете что :-) - SS:ESP(30.10.2013 14:26, )
- Не знаешь о современных пик-контроллерах -- не пиши ерунды. Не самый плохой 16-битный CPU, однозначно лучше во всех смыслах ваших любительских AVR'ов. - fk0(30.10.2013 14:09)
- Уж лучше 32 регистра r0-r31 и нормальный стек "искаропки"... Хотя пройденный этап. По сравнению с однотактным умножением 32x32 и прочими ништяками - SS:ESP(30.10.2013 13:50, )
- это в 8-ми битниках, но там и ртос кооперативная. А в 16-ти битниках уже трап по переполнению. - abivan(30.10.2013 12:11)
- В пиках давно уже и стек нормальный и 14-шт WREG'ов. Жить стало лучше, жить стало веселее. - fk0(30.10.2013 12:29)
- В ПИКах "аппаратный" стек из 8 слов. "640 килобайт хватит на всех" (c) Билли - SS:ESP(30.10.2013 11:53, )
- Для этого в контроллерах проф. уровня есть регистр указывающий на максимальную глубину стека. При переходе -- исключение. Без всяких MMU. - fk0(30.10.2013 11:34)
- вы понимаете, что потоки в контроллере практически всегда имеют сильные взаимосвязи по данным между собой. Mahagam(144 знак., 30.10.2013 11:05)
- И так повторять два десятка раз (по числу задач, каждая использует свой стек в вытесняющей операционке). Смеётесь или не понимаете, что такое многозадачная вытесняющая RTOS? - VVB(30.10.2013 09:33)
- А не есть ли задача операционной системы следить за переполнением/переопустошением стека операциями push/pop и обрабатывать исключение по вектору, скажем, 0Ch, как это реализовано в процессоре - Intel 80386(29.10.2013 21:39, )
- вы уж определитесь, процессором это ловить или операционной системой. - Mahagam(29.10.2013 21:42)
- Процессор генерирует исключение. Операционная система предоставляет код. Скажем при переполнении увеличивает стек на 4 Килобайта. - Intel 80386(29.10.2013 21:49, )
- отож, сегодня каждый первый процессор умеет генерить исключения по переполнению локального стека задачи. ага. - Mahagam(29.10.2013 22:48)
- Процессор генерирует исключение. Операционная система предоставляет код. Скажем при переполнении увеличивает стек на 4 Килобайта. - Intel 80386(29.10.2013 21:49, )
- вы уж определитесь, процессором это ловить или операционной системой. - Mahagam(29.10.2013 21:42)
- Не совсем понял, как именно gprof позволяет понять stack usage, можно поподробнее? - fk0(29.10.2013 16:32)
- Ну как же... (только для run-time, нет расчёта для наихудшего случая, в отличие от MULTI или Keil). Кстати, MULTI основан на GCC, ему для расчёта нужен .dnm файл, генерируемый линкером - VVB(29.10.2013 17:03 - 17:06, ссылка)
- Не понял (в ссылке l на конце нет). Там ни слова о стеке. Только call graph. Но это и без gprof можно, хотя и весьма вероятностно... (cflow). Но в варианте с gprof не лучше: где гарантия, что прокрутились _все_ варианты выполнения программы? Их fk0(204 знак., 29.10.2013 17:10)
- так как рамы у меня в проекте валом, то завёл сервисный поток, который Mahagam(231 знак., 29.10.2013 21:37)
- Не понял (в ссылке l на конце нет). Там ни слова о стеке. Только call graph. Но это и без gprof можно, хотя и весьма вероятностно... (cflow). Но в варианте с gprof не лучше: где гарантия, что прокрутились _все_ варианты выполнения программы? Их fk0(204 знак., 29.10.2013 17:10)
- Ну как же... (только для run-time, нет расчёта для наихудшего случая, в отличие от MULTI или Keil). Кстати, MULTI основан на GCC, ему для расчёта нужен .dnm файл, генерируемый линкером - VVB(29.10.2013 17:03 - 17:06, ссылка)
- Stackoverflow - хороший сайт. - SciFi(29.10.2013 15:32, ссылка)
- Натолкнуло на интересную мысль применительно к embedded программированию. А именно -fsplit-stack. Будучи допиленным до рабочего вида на пик-контроллерах любого практически уровня оно позволит забыть навсегда о protothreads и др. извращениях: на fk0(453 знак., 29.10.2013 16:28, ссылка)
- У кейла в RTX51 что-то подобное. IMHO, прототреды удобнее. - Mebius(29.10.2013 21:25)
- Активно им пользуюсь, но не смог этой ссылки найти. VVB(442 знак., 29.10.2013 15:53)
- А где именно лучше? И как оно выглядит? - fk0(29.10.2013 16:31)
- Хотя бы вот так VVB(229 знак., 29.10.2013 16:58)
- И вот так для Keil VVB(29.10.2013 17:00)
- Примерно так же умеет компилятор проф. уровня им. hitech software. Но увы, доворовались, код отдан индусским студентам. Хотя тоже не панацея: все случаи (а они могут зависеть от входных данных) просмотреть не может. Типичный пример: qsort. Можно, fk0(1037 знак., 29.10.2013 17:18)
- Понятно, что расчёты стека по указателям не провести. Я хотел узнать о простых возможностях. Статический анализ кода (cflow) это примитив, вообще не дающий понимания о ресурсах, которые будет жрать CRT или окружение С++, в случае работы над VVB(1847 знак., 29.10.2013 21:09)
- GCC не умеет. - VVB(29.10.2013 18:41)
- Примерно так же умеет компилятор проф. уровня им. hitech software. Но увы, доворовались, код отдан индусским студентам. Хотя тоже не панацея: все случаи (а они могут зависеть от входных данных) просмотреть не может. Типичный пример: qsort. Можно, fk0(1037 знак., 29.10.2013 17:18)
- И вот так для Keil VVB(29.10.2013 17:00)
- Хотя бы вот так VVB(229 знак., 29.10.2013 16:58)
- Ну а что, гэцэцэ - "жалкая паделка финских студентов" © Ведь не зря эта присказка появилась :-) - SciFi(29.10.2013 16:09)
- Они пришли из другой вселенной (ПК), им позволительно иметь профилировщик gprof и туда всё зафигачить. Но если ползут вниз, то пускай добавляют удобный инструментарий. - VVB(29.10.2013 16:13)
- Несите бапки в - Йар(29.10.2013 16:12, )
- А где именно лучше? И как оно выглядит? - fk0(29.10.2013 16:31)
- Натолкнуло на интересную мысль применительно к embedded программированию. А именно -fsplit-stack. Будучи допиленным до рабочего вида на пик-контроллерах любого практически уровня оно позволит забыть навсегда о protothreads и др. извращениях: на fk0(453 знак., 29.10.2013 16:28, ссылка)
- Напоминаю классический способ, не зависящий от компилятора. При запуске прописать область стека каким-нибудь характерным кодом, после выполнения посмотреть, где этот код уцелел. - vmp(29.10.2013 22:05)