|
Размер структур, стек и куча, Максимальный размер структур, их копирование, стек и куча |
|
|
|
Dec 22 2015, 16:07
|

Местный
  
Группа: Участник
Сообщений: 240
Регистрация: 14-04-10
Из: Россия, г.Челябинск
Пользователь №: 56 634

|
Пишем программу для нового прибора. Коллега создает вот такие структуры: Код typedef struct { REC_HEADER Header; WORD NoPT; WORD NoPL; WORD NoAD; WORD StationID; WORD ModelID; WORD ManufactID; char Ident[9]; char Descript[41]; WORD StatTime; WORD NoFR; WORD NoRT; WORD NoBL; BYTE NoKY; BYTE NoPR; BYTE UnitsCal[7]; float Units0dB[7]; char KeyId[3][5]; char KeyDescr[3][41]; BYTE KeyGrade[3]; float Factor[3]; BYTE KeyTStamp[3][8]; float KeyNom[3]; float RPM[3]; char KeyNotes[3][241]; char PrId[12][9]; char PrDescr[12][41]; char Units[12][7]; BYTE PrGrade[12]; BYTE PrTStamp[12][8]; float PrNom[12]; float PrVal[12]; char PrNotes[12][241]; } RTN; и вот в таком вот месте программа "виснет" Код void make_TA(void) { BYTE get_status(BYTE);
RTN train=TRAIN; // ТУТ ЗАВИСАЕТ Увеличил размер стека и все заработало. Был 3кБ сделал 10кБ. Правда, из SCRTACHPAD пришлось перенести в L1 из-за размера. Контроллер Blackfin BF-548. Теперь вопросы: 1. Как вы контролируете переполнение стека? 2. Какой размер считаете оптимальным? 3. В какой памяти его лучше располагать? 4. Как реально происходит приравнивание структур? Это спрятанное от глаз memcpy? И используется ли при этом динамическое выделение памяти? 5. Мириться ли с тем, что коллега создает такие огромные структуры или надо сменить подход? Можно ли их располагать в функции или лучше глобально?
|
|
|
|
|
Dec 22 2015, 16:55
|
Участник

Группа: Участник
Сообщений: 66
Регистрация: 17-12-15
Пользователь №: 89 731

|
при вызове Си-шной функции все параметры, которые получает и возвращает функция, передаются через стек. если не побоитесь, то можно работать с указателями на эти структуры, тогда лишнего копирования можно избежать.
|
|
|
|
|
Dec 22 2015, 17:08
|

Местный
  
Группа: Участник
Сообщений: 240
Регистрация: 14-04-10
Из: Россия, г.Челябинск
Пользователь №: 56 634

|
Цитата(Сергей Борщ @ Dec 22 2015, 22:39)  4) Да, memcpy. Нет, куча не используется. А зачем она могла бы при этом понадобиться? Не знаю. Подумал, может создается копия, а потом копируется для случая memcpy с перекрывающимися областями памяти. Цитата(Сергей Борщ @ Dec 22 2015, 22:39)  5) Если нужна именно такая структура, то что вы тут сможете поменять? Ну как-то сделать свою часть программы такой, чтобы не было таких огромных локальных переменных. Пусть они будут, но не локальными переменными же. Если подойти к этому с размахом то там и мегабайтные маассивы начнут локально объявлять. Так никакого стека не хватит. А про размер - ну просто из опыта работы. Какой делали максимальным на приборе с МК такого класса и 32-64 МБ ОЗУ
|
|
|
|
|
Dec 22 2015, 21:03
|

Ally
     
Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050

|
Цитата(kolobochishe @ Dec 22 2015, 19:08)  А про размер - ну просто из опыта работы. Какой делали максимальным на приборе с МК такого класса и 32-64 МБ ОЗУ А что у вас за прибор? Стек он в дивайсах с реальным временем на вес золота. Ибо организуется в быстрой внутренней RAM, даже TCM RAM. А все такие структуры сносятся в медленную внешнюю RAM в heap. Имея такие ресурсы как у вас всегда применяют RTOS. А у развитых RTOS всегда есть механизмы наблюдения за стеком. Причем в реальном времени. У меня даже на платах с 128 МБ памяти стек задач никогда не превышал 5 Кб. Если нужно больше, то это уже какие-то проблемы с софтом. Только когда речь шла о слишком замороченном стороннем софте например задачах клиентских сессий со встроенным WEB сервером стек увеличивал до 10 кб. А коллегу вашего надо переучивать. Факт.
|
|
|
|
|
Dec 23 2015, 05:45
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(kolobochishe @ Dec 22 2015, 22:07)  1. Как вы контролируете переполнение стека? 2. Какой размер считаете оптимальным? 3. В какой памяти его лучше располагать? 4. Как реально происходит приравнивание структур? Это спрятанное от глаз memcpy? И используется ли при этом динамическое выделение памяти? 5. Мириться ли с тем, что коллега создает такие огромные структуры или надо сменить подход? Можно ли их располагать в функции или лучше глобально? 5. Коллеге за такое в embedded без внешней памяти, надо не просто по рукам бить, а ампутировать их. Лучше не данные, а коллегу расположить где-нить в вынь-программинге. 2. Оптимальных размеров стека нет, есть необходимые. 1. Контроль - заполнением шаблоном. 3. Лучше внутренней, особенно касаемо DSP с его огромными контекстами. 4. Согласно языка си: поэлементно. Распределение памяти и инициализация - вещи суть разные и почти несвязанные. Цитата(quarter @ Dec 22 2015, 22:55)  при вызове Си-шной функции все параметры, которые получает и возвращает функция, передаются через стек. ложь. Цитата(AlexandrY @ Dec 23 2015, 03:03)  Стек он в дивайсах с реальным временем на вес золота. Ибо организуется в быстрой внутренней RAM, даже TCM RAM. В принципе можно и во внешней памяти стек располагать, даже на устройствах где есть жёсткий реалтайм. Всё зависит от требуемого быстродействия данной задачи ОС и архитектуры CPU. Если архитектура такова, что при возникновении прерывания контекст сохраняется на другом стеке (как на Cortex) или вообще не сохраняется (как в ARM TDMI), то стек некоей медленной задачи расположенный во внешней ОЗУ никак не затормозит ISR, но может затормозить переключение контекста данной медленной задачи ОС. Как обстоит дело с сохранением контекста в Блэкфинах я не знаю.
|
|
|
|
|
Dec 23 2015, 06:44
|
Знающий
   
Группа: Свой
Сообщений: 526
Регистрация: 5-08-05
Пользователь №: 7 390

|
Цитата(kolobochishe @ Dec 22 2015, 19:07)  Код void make_TA(void){
RTN train=TRAIN; // ТУТ ЗАВИСАЕТ у вас в стеке создается копия статической или глобальной структуры. Лучше использовать указатель Код void make_TA(RTN* train){
train->NoPt = ...; или ссылку, если это С++
|
|
|
|
|
Dec 23 2015, 06:58
|

Ally
     
Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050

|
Цитата(SlavaV @ Dec 23 2015, 08:52)  PPS все функции работы с памятью memcpy malloc работают с кучей А это не закон. Как в программе переопределено так и будет. Скажем RTOS-ы сразу переопределяют эти функции. А там у кого как, у кого куча, а у кого и много куч. Но все со своими оригинальными движками. Кстати не додумал, но коллега действительно мог использовать стек именно для ускорения своей процедуры. Либо вообще копипастить из среды моделирования один в один. Тогда это оправдано и придираться к нему нельзя.
|
|
|
|
|
Dec 23 2015, 08:14
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(SlavaV @ Dec 23 2015, 12:52)  Вообще конструкция тип НовыйОбъект = Объект говорит создать временный объект типа "тип" (вот он видимо и создаётся на стеке) и скопировать его в НовыйОбъект (именно скопировать, если не перегружен оператор= происходит почленное копирование) Не обязательно. Если TRAIN - имеет тип RTN и перегружен оператор присваивания: RTN & RTN::operator =(RTN &); то (имхо) компилятор сделает вызов конструктора по умолчанию RTN::RTN(), а затем для созданного объекта вызовет этот перегруженный оператор присваивания: train(TRAIN)
|
|
|
|
|
Dec 23 2015, 08:29
|
Частый гость
 
Группа: Свой
Сообщений: 100
Регистрация: 13-06-06
Из: г.Улан-Удэ
Пользователь №: 18 024

|
Цитата(jcxz @ Dec 23 2015, 17:14)  Не обязательно. Если TRAIN - имеет тип RTN и перегружен оператор присваивания: RTN & RTN::operator =(RTN &); то (имхо) компилятор сделает вызов конструктора по умолчанию RTN::RTN(), а затем для созданного объекта вызовет этот перегруженный оператор присваивания: train(TRAIN) вот этот объект и создаётся на стеке (вернее в автоматической памяти, а она обычно на стеке) здесь можно обойтись без стека (автоматической памяти) Вы правильно сказали используя конструктор, но в коде нет этого, да и вопрос был почему не работает, а не как сделать чтоб работало
|
|
|
|
|
Dec 23 2015, 09:08
|

Местный
  
Группа: Участник
Сообщений: 240
Регистрация: 14-04-10
Из: Россия, г.Челябинск
Пользователь №: 56 634

|
Цитата(AlexandrY @ Dec 23 2015, 02:03)  ... Имея такие ресурсы как у вас всегда применяют RTOS. А у развитых RTOS всегда есть механизмы наблюдения за стеком. ... Решили не использовать, т.к. задача одна, а библиотека драйверов наличия ОС не требует. Забыл упомянуть - пишем на СИ без плюсов. Цитата(AlexandrY @ Dec 23 2015, 11:58)  ... Кстати не додумал, но коллега действительно мог использовать стек именно для ускорения своей процедуры. Либо вообще копипастить из среды моделирования один в один. Тогда это оправдано и придираться к нему нельзя. Не думаю, что для ускорения. Пишет под WIN32, потом передает мне те части, которые платформо-независимы
|
|
|
|
|
Dec 23 2015, 09:10
|

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

|
Цитата(psL @ Dec 23 2015, 09:44)  у вас в стеке создается копия статической или глобальной структуры. Лучше использовать указатель Кому лучше? Если там создается копия - наверное программисту нужна именно копия, он хочет ее менять, а содержимое оригинала потом потребуется в другом месте. А если можно работать с содержимым оригинальной струкьтуры, то и в этом случае указатель не нужен - можно работать прямо с самой структурой. Цитата(SlavaV @ Dec 23 2015, 09:52)  PPS все функции работы с памятью memcpy malloc работают с кучей Каким местом memcpy связан с кучей? Цитата(SlavaV @ Dec 23 2015, 11:29)  Вы правильно сказали - используя конструктор, Судя по "typedef struct" там голый Си, без плюсов.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Dec 23 2015, 09:21
|

Ally
     
Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050

|
Цитата(kolobochishe @ Dec 23 2015, 11:08)  Не думаю, что для ускорения. Пишет под WIN32, потом передает мне те части, которые платформо-независимы Ну так бы сразу и сказали. А то вводите публику в заблуждение. В Win32 он может писать как ему вздумается, и ничего ему за это не будет. Вы портируете эти куски, вы и отвечаете за стек. Просто портировать лень, да?
|
|
|
|
|
Dec 23 2015, 09:27
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(Сергей Борщ @ Dec 23 2015, 15:10)  Судя по "typedef struct" там голый Си, без плюсов. Никто не мешает использовать "typedef struct" под с++. Цитата(AlexandrY @ Dec 23 2015, 15:21)  В Win32 он может писать как ему вздумается, и ничего ему за это не будет. Вы портируете эти куски, вы и отвечаете за стек. Именно так, согласен. Я сразу и написал, что это виндузятный подход, а не ембеддед.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|