Для программы из http://bellard.org/mersenne.html GCC создает исполняемый файл размером ~ 130 МБ. Почему?
1 ответ
Попробуйте изменить t[1<<25]={2}
на t[1<<25]
, и размер * исполняемого файла ** уменьшится до 7,3 КБ . (Излишне говорить, что вы не получите правильных результатов)
Если бы это было просто t[1<<25]
, оно бы вообще не заняло места.
Загвоздка здесь в том, что массив инициализируется (первый элемент = 2, следующие 2 ^ 25-1 элементов все 0), а глобальный массив помещается в сегмент данных только потому, что он инициализирован. .
Генерация сборки для двух версий и изучение различий делает ее еще более понятной:
[axiom@axiom ~]$ diff without_mem.s with_mem.s
15c15,21
< .comm t,134217728,32
---
> .globl t
> .align 32
> .type t, @object
> .size t, 134217728
> t: ***<- HERE!***
> .long 2
> .zero 134217724
Как мы можем заметить, в исходной версии ассемблер направлен на создание 2 ^ 27 (134217728) байтов в сегменте данных. Таким образом, он становится частью самого объектного файла. ( Вы можете сгенерировать сборку путем компиляции с помощью переключателя -S
gcc -S -fverbose-asm t1.c
)
Но почему 129 МБ?
1<< n= 2^n (1 left shifted n times). => 1<<25=2^25. now 1 Integer= 4 bytes =2^2 bytes => 2^25 Integers=2^27 bytes=2^7 * 1 M bytes= 128 MBs
Для получения дополнительной информации см.:
*Примечание 1: это Объектный файл В строгих условиях.
Примечание 2: Как указано в комментариях, можно также отметить, что общий размер процесса (выполняемой программы) будет 129 МБ, даже если размер исполняемого файла составляет 7,3 КБ. (Память будет выделена после начала выполнения программы). Вы можете увидеть использование памяти вашей программой, используя команду top
.
Примечание 3: стоит подчеркнуть, что это справедливо только потому, что t является глобальным. Распределение данных, локальных для функции, по-прежнему происходит во время выполнения в стеке. Таким образом, если бы t
был локальным, объектный файл занял бы всего 7,3 КБ.
Примечание 4: Инициализированные локальные переменные static
, как и инициализированные глобальные переменные, также хранятся в сегменте data
. Глобальное значение static
то же , что и глобальное, за исключением того, что вы ограничиваете область действия переменной только текущим файлом.
memset
. Может быть, используются какие-то странные флаги оптимизации или отладки?
Похожие вопросы
Новые вопросы
c
C - это язык программирования общего назначения, используемый для системного программирования (ОС и встраиваемых), библиотек, игр и кроссплатформенности. Этот тег следует использовать с общими вопросами, касающимися языка C, как это определено в стандарте ISO 9899 (последняя версия 9899: 2018, если не указано иное, а также для запросов, специфичных для версии, с c89, c99, c11 и т. Д.). C отличается от C ++ и не должен сочетаться с тэгом C ++ без разумной причины.