Когда вы беспокоитесь о размере стека?

Я бы рекомендовал eventlet и зеленые потоки для этого.

Twisted - хорошая библиотека, но небольшая крутая кривая обучения для такого простого использования.

Ознакомьтесь с некоторыми примерами здесь .

13
задан Tarquila 16 December 2009 в 16:34
поделиться

17 ответов

У меня были проблемы с нехваткой места в стеке в следующих случаях:

  • Функция случайно вызывает себя
  • Функция использует рекурсию на глубокий уровень
  • Функция выделяет большой объект в стеке, и есть heap.
  • Функция использует сложные шаблоны, и компилятор дает сбой

При условии I:

  • Размещение больших объектов в куче (например, с использованием «auto_ptr foo = new Foo» вместо «Foo foo»)
  • Используйте рекурсию с умом.

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

0
ответ дан 1 December 2019 в 17:20
поделиться

Не знаю. Беспокойство об этом при написании нормальных программных вещей - это либо преждевременная пессимизация, либо преждевременная оптимизация. В любом случае, довольно сложно что-то взорвать на современном компьютере.

Однажды я написал парсер CSV и, играя с попытками добиться максимальной производительности, я размещал в стеке сотни тысяч буферов размером 1 КБ. Производительность была звездной, но объем оперативной памяти увеличился примерно до 1 ГБ с обычных 30 МБ. Это произошло из-за того, что каждая ячейка в CSV-файле имела буфер фиксированного размера 1 КБ.

Как все говорят, если вы не выполняете рекурсию, вам не нужно об этом беспокоиться.

1
ответ дан 1 December 2019 в 17:20
поделиться

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

Если я хочу выделить очень большой объект, то вместо этого в стеке Я мог бы выделить его в куче, но обернуть в auto_ptr (в этом случае он будет освобожден, когда он выйдет за пределы области видимости, как и объект в стеке, но не беспокоясь о размере стека).

... когда и как вы беспокоитесь о размере стека?

Я использую стек консервативно по привычке (например, вместо этого в куче выделяется любой объект размером более 512 байт), и я знаю, насколько велик стек есть (например, около мегабайта по умолчанию), и поэтому знаю, что мне не нужно об этом беспокоиться.

Есть ли какие-то практические правила для рассуждений о размере стека?

  • Очень большие объекты могут разрушить стек
  • Очень глубокая рекурсия может разрушить стек
  • Размер стека по умолчанию может быть слишком большим (занимает слишком много общая память), если имеется много потоков и если вы работаете на встроенном устройстве с ограниченным объемом памяти, и в этом случае вы можете использовать O / S API или параметр компоновщика, чтобы уменьшить размер стека на поток.
13
ответ дан 1 December 2019 в 17:20
поделиться

В общем, большие выделения в стеке - это плохо по нескольким причинам, не в последнюю очередь из-за того, что они могут заставить проблемы оставаться хорошо скрытыми в течение длительного времени.

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

Если процессор не имеет блока управления памятью или защиты памяти, вы должны быть особенно осторожны. Но в случае с каким-то MMU или MPU оборудование может не обнаружить переполнение стека. Одна из распространенных схем - резервирование страницы под стеком на случай переполнения - не работает, если большой объект стека больше, чем страница. Там просто может быть стопка другого потока, и ой! вы только что создали очень неприятную ошибку, которую трудно найти.

1
ответ дан 1 December 2019 в 17:20
поделиться

При принятии решения о размещении объектов в стеке или в куче необходимо также учитывать проблемы производительности во внимание. Выделение памяти в стеке происходит очень быстро - оно просто включает перемещение указателя стека, тогда как динамическое выделение / освобождение с использованием new / delete или malloc / free довольно дорого, особенно в многопоточном коде, у которого нет кучи на поток. Если у вас есть функция, которая вызывается в жестком цикле, вы вполне можете ошибиться, помещая в стек более крупные объекты, не забывая о всех предостережениях в отношении многопоточности, упомянутых в других ответах, даже если это означает необходимость увеличения стека. пространство, которое позволяет сделать большинство линкеров.

1
ответ дан 1 December 2019 в 17:20
поделиться

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

CreateThread по умолчанию выделяет для стека только 0x100000 байт.

2
ответ дан 1 December 2019 в 17:20
поделиться

Обычно большие объекты не помещаются в стек. Они почти всегда используют кучу внутренне, поэтому, даже если они находятся «в стеке», их элементы данных нет. Даже объект с множеством элементов данных обычно будет меньше 64 байтов в стеке, а остальные - в куче. Стек обычно становится проблемой в наши дни, когда у вас много потоков и много рекурсии.

2
ответ дан 1 December 2019 в 17:20
поделиться

Много играл в эту игру на Symbian: когда использовать TBuf (строка с хранилищем в стеке), а когда использовать HBufC (которая выделяет хранилище строк в куче, например std: : string, поэтому вам нужно справиться с Leave, а вашей функции нужны средства для отказа).

В то время (возможно, я все еще не уверен), потоки Symbian по умолчанию имели стек размером 4 КБ. Чтобы управлять именами файлов, вам нужно рассчитывать на использование до 512 байт (256 символов).

Как вы понимаете, полученная мудрость заключалась в том, чтобы «никогда не помещать имя файла в стек». Но на самом деле оказалось, что это может сойти с рук гораздо чаще, чем вы думаете. Когда мы начали запускать настоящие программы (TM), такие как игры, мы обнаружили, что нам все равно нужно намного больше, чем размер стека по умолчанию, и это было не из-за имен файлов или других конкретных больших объектов, это произошло из-за сложности кода игры.

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

t имеют несколько уровней функций обработки файлов, которые все помещают имя файла в стек), тогда я бы сказал, просто попробуйте. Особенно, если функция все равно должна иметь возможность сбой, независимо от того, используете ли вы стек или кучу. Если что-то пойдет не так, вы либо удвоите размер стека и будете более осторожны в будущем, либо добавите еще один случай сбоя в свою функцию. Нет и конца света.

t имеют несколько уровней функций обработки файлов, которые все помещают имя файла в стек), тогда я бы сказал, просто попробуйте. Особенно, если функция все равно должна иметь возможность сбой, независимо от того, используете ли вы стек или кучу. Если что-то пойдет не так, вы либо удвоите размер стека и будете более осторожны в будущем, либо добавите еще один случай сбоя в свою функцию. Нет и конца света.

2
ответ дан 1 December 2019 в 17:20
поделиться

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

2
ответ дан 1 December 2019 в 17:20
поделиться

Когда вас беспокоит размер стека?

Никогда.

Если у вас есть проблемы с размером стека, это означает, что вы делаете что-то еще не так, и вам следует исправить это, а не беспокоиться о размере стека.
Для примера:

  • Размещение в стеке неоправданно больших структур - не делайте этого. разместить в куче.
  • Имея до смешного длинную рекурсию. Я имею в виду порядок рисования изображения и перебора пикселей с использованием рекурсии. - найдите лучший способ сделать это.
3
ответ дан 1 December 2019 в 17:20
поделиться

мой опыт: когда вы используете рекурсивные функции, позаботьтесь о размере стека !!

3
ответ дан 1 December 2019 в 17:20
поделиться

Разве вам не следует в первую очередь избегать использования стека для размещения больших объектов? Использовать кучу, не так ли?

3
ответ дан 1 December 2019 в 17:20
поделиться

Я никогда не беспокоюсь об этом. Если произойдет переполнение стека, я скоро узнаю об этом. Кроме того, в C ++ очень сложно создавать очень большие объекты в стеке. Единственный способ сделать это:

struct S {
   char big[1000000];
};

, но использование std :: string или std :: vector решает эту проблему.

4
ответ дан 1 December 2019 в 17:20
поделиться

If you're writing for a tiny little embedded platform, you worry about it all the time, but you also know exactly how big it is, and probably have some useful tools available to find the high-water mark of the stack.

If you aren't, then don't worry until your program crashes :) Если вы не выделяете очень большие объекты (многие десятки КБ), это никогда не будет проблемой.

Обратите внимание, однако, что объекты в стеке по определению являются временными. Часто создание (и, возможно, разрушение) больших объектов может вызвать проблемы с производительностью - поэтому, если у вас большой объект, он, вероятно, должен быть постоянным и основанным на куче по причинам, отличным от размера стека.

6
ответ дан 1 December 2019 в 17:20
поделиться

Вы заботитесь об этом на микроконтроллере, где вам часто приходится явно указывать пространство стека (или вы получаете все, что остается после того, как ОЗУ используется для статического распределения + любое пространство программы ОЗУ).

11
ответ дан 1 December 2019 в 17:20
поделиться

Вы начинаете беспокоиться о размере стека, когда

  • кто-то из вашей команды хитро изобретает рекурсивную функцию, которая продолжается, повторяется и повторяется ...
  • вы создаете фабрику потоков и внезапно вам нужен десятикратный стек, который вам нужен (каждому потоку нужен стек => чем больше у вас потоков, тем меньше свободного места остается для данного размера стека)
7
ответ дан 1 December 2019 в 17:20
поделиться

Вы беспокоитесь об этом, когда пишете обратный вызов, который будет вызываться из потоков, порожденных средой выполнения, которую вы не контролируете (например, среда выполнения MS RPC) с размером стека по усмотрению этого время выполнения. Как-то вот так .

0
ответ дан 1 December 2019 в 17:20
поделиться
Другие вопросы по тегам:

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