Сегмент данных против стека
Глобальная переменная размещается в сегменте данных, а локальная остается в стеке. Я знаю, что доступ к переменной, хранящейся в куче, медленнее, чем доступ к локальной переменной, но я не знаю, быстрее ли доступ к локальной переменной, чем к глобальной. Это зависит от компилятора? Значимы ли различия или нет?
2 ответа
Stack и head являются только деталями реализации, что означает, что они могут зависеть от среды компиляции. Стандарт C определяет только связь и продолжительность хранения идентификаторов. Но вы правы, стек, куча и сегмент данных являются общей реализацией.
Но вы ошибаетесь, когда говорите, что доступ к переменной, хранящейся в куче, медленнее, чем доступ к локальной переменной. Выделение и освобождение динамической памяти действительно более сложное и занимает больше времени, чем использование автоматических переменных, но в течение срока их службы доступ (будь то для чтения или записи) стоит точно так же - по крайней мере, в общей инфраструктуре. Что будет иметь значение:
- данные в кэше процессора или в кэше уровня 2 (ускоряет доступ)
- данные на текущей обмениваемой странице, которые необходимо перезагрузить с диска (замедляет доступ)
Но и то, и другое может происходить одинаково для динамических, автоматических или статических данных...
Прочтите также эту статью, прежде чем читать дальше (я не говорю о доступе к стеку или кучи):
Доступ к данным в куче быстрее, чем из стека?
Архитектуры и политики управления памятью настолько различны, что об этом трудно говорить. Я возьму Intel x86 в качестве примера.
Доступ к данным осуществляется с помощью одной инструкции, где бы мы ни находились.
INST означает инструкцию, которую мы выполняем. SEG обозначает, к какому сегменту мы обращаемся. А VADDR обозначает виртуальный адрес.
В реальном режиме SEG будет базовым адресом для сегмента, а ADDR будет внутренним адресом для сегмента. Эффективность доступа к данным в реальном режиме одинакова для всех сегментов. (Независимо от стека, кучи или глобального)
В защищенном режиме SEG будет селектором, а ADDR - виртуальным адресом. И самое сложное в том, что MMU (модуль управления памятью) начинает работать и обвиняет тех, кто получает доступ к данным "не ожидается".
Когда данные, к которым вы обращаетесь, находятся не в памяти, MMU генерирует прерывание сбоя страницы и просит ОС переключать страницы. А MMU обвиняет вас, тратя больше времени на обмен страницами с жестким диском.
Так что просто напрасно говорить о том, быстрее ли он получает доступ к глобальным или локальным данным, не учитывая, как к ним осуществляется доступ.
С моей точки зрения, у вас больше шансов получить доступ к "локальным данным" стека, чем к глобальным данным, поэтому вероятность доступа к странице может быть выше при доступе к глобальной.