сравнение производительности доступа к данным в куче и стеке

Общеизвестно, что для большинства алгоритмов выделение и освобождение данных в стеке происходит намного быстрее, чем в куче. В C++ разница в коде примерно такая

double foo[n*n]

vs.

double* foo = new int[n*n]

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

foo[i]

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


person shuhalo    schedule 11.08.2010    source источник
comment
Если это поможет, вот простой тест, который просто читает и записывает в каждый элемент большого массива. На моей машине он работает как минимум в 5 раз быстрее, когда массив находится в стеке.   -  person Gumby The Green    schedule 05.05.2019


Ответы (4)


Могут быть (сильно зависящие от системы) проблемы с расположением кеша и промахами чтения/записи. Если вы запускаете свою программу на данных стека и кучи, то вполне возможно (в зависимости от архитектуры вашего кэша), что вы столкнетесь с большим количеством промахов кэша, чем если бы вы запускали ее полностью в одной непрерывной области памяти. стек. Вот статья по этому вопросу Эндрю Аппеля (из SML/NJ) и Чжун Шао, где они исследуют именно эту вещь, потому что выделение стека/кучи является темой для реализации функциональных языков:

http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.48.3778

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

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

person Nordic Mainframe    schedule 11.08.2010

Стек будет чаще находиться в кэше ЦП, поэтому в некоторых (в большинстве?) случаях это может быть быстрее.

Но самый точный ответ, наверное, таков: это зависит...

person Michel de Ruiter    schedule 11.08.2010

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

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

  • Само выделение стека немного дешевле, чем выделение кучи, потому что выделение проще.

  • В долгосрочной перспективе основной проблемой кучи обычно является фрагментация, «накопленная стоимость», которая (обычно) не может быть отнесена к отдельным выделениям, но может значительно увеличить стоимость дальнейших выделений.

Измерение этих эффектов, по крайней мере, сложно.

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

person peterchen    schedule 11.08.2010

За исключением распределения, не должно быть заметной разницы между доступом к данным, будь то в стеке или в куче — в конце концов, это вся память.

person Will A    schedule 11.08.2010