Статический против глобального с точки зрения скорости и потребления пространства в C - PullRequest
6 голосов
/ 27 ноября 2008

Хотелось бы узнать разницу между статическими и глобальными переменными с точки зрения скорости доступа и потребления пространства . (Если вы хотите узнать мою платформу: компилятор gcc в Windows. (Я использую Cygwin с Triton IDE для встроенного программирования ARM7 в Windows. Triton поставляется с компилятором gcc на платформе Java, который можно запустить в Windows.))

(Очевидно, я знаю с точки зрения объема файлов и функций из этот вопрос )

Редактировать: ОК, дайте мне ответ на любом микроконтроллере / процессорной среде.

Ответы [ 6 ]

11 голосов
/ 27 ноября 2008

Нет разницы для места, они занимают одинаковое количество.

Но есть разница в скорости: статика быстрее.

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

С помощью gcc вы можете одновременно передавать все .c источники, поэтому он также может видеть, что происходит при вызове функций для функций из разных модулей. Чтобы это работало, вы должны передать все .c файлы одновременно -combine и -fwhole-program. -fwhole-program делает все глобальные переменные статическими (не статическими, а статическими модулями компиляции, то есть все указанные файлы .c вместе) -combine выполняет межмодульный анализ.

1 голос
/ 27 ноября 2008

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

1 голос
/ 27 ноября 2008

Трудно догадаться или оценить. Это, вероятно, займет время, но я бы сделал пример проекта и проверил скорость. Проверка скорости доступа и пространства с помощью цикла. Протестируйте пример проекта с эмулятором для этой архитектуры.

1 голос
/ 27 ноября 2008

Потребление места: в основном без разницы. Единственный раз, когда возникнет проблема с пространством, если вам удастся получить тот же кусок статических данных, скрытых в N объектных файлах, тогда вы получите коэффициент умножения N, где у вас может быть только 1 копия, если это будет один глобальный фрагмент данных. Однако это проблема неправильного дизайна. Сокрытие информации - это хорошо - если только информация не должна быть скрыта.

Скорость доступа: без разницы.

0 голосов
/ 10 декабря 2008

То, что говорит Джонатан, не совсем верно. Как статические, так и глобальные переменные будут (должны быть) сохранены в областях ZI (или данных RW). Компилятор не может строго «держать» его над регистром - что он может сделать, это загрузить значение в регистр, использовать этот регистр для всех операций и затем сохранить это значение обратно - это специфическая оптимизация компилятора. И даже тогда, нет никаких причин, почему компилятор не будет делать это и для глобальных переменных: если, конечно, вы не сделаете его изменчивым. Но с технической точки зрения вы также можете сделать статическую переменную изменчивой, так что опять без разницы.

Редактировать: о да - пробел: без разницы.

0 голосов
/ 27 ноября 2008

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

Для скорости соображений (, но не для хорошей практики ) вы можете предпочесть глобальные переменные , если вам нужен доступ к var вне одного файла. (ссылка на использование external char my_global_char_placed_else_where;)

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

Если вы сравниваете скрытие переменной внутри функции, то нет никакой разницы по сравнению с размещением ее вне функции, и больше функций может иметь доступ к переменной.

Я сам использую MSP430, ARM7 (только для тестов) и AVR32 micros для разработки

...