2012-12-13 1 views

답변

12

t[1<<25]={2}t[1<<25]으로 변경하고 * 실행 파일 **의 크기가 7.3 K으로 떨어집니다. (말할 필요도없이 올바른 결과를 얻지 못할 수도 있습니다)

단지 t[1<<25]이라면 전혀 공간을 차지하지 않았을 것입니다. 여기

캐치 배열 (제 1 요소 = 2, 다음 2^25-1 요소 모두 0)으로 초기화되고, 그리고이 초기화되기 때문에 글로벌 어레이 데이터 세그먼트 을 배치 도착이다.


2 버전에 대한 어셈블리를 생성하고 그 차이를 조사하는 것은 만드는 것이 훨씬 더 분명 우리가 알 수 있듯이, 원래 버전에서, 어셈블러는 2^27 (134,217,728) 바이트를 생성하도록 지시한다

[[email protected] ~]$ 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 

데이터 세그먼트. 따라서 객체 파일 자체의 일부가됩니다. (-S 스위치로 컴파일하여 어셈블리를 생성 할 수 있습니다. gcc -S -fverbose-asm t1.c


왜 129 MB입니까?
 
    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 : 그것은 엄격한 측면에서 object file입니다.

주 2 : 주석에서 지적했듯이 실행 파일이 7.3K 인 경우에도 프로세스 (실행중인 프로그램)의 전체 크기는 129MB가됩니다. (프로그램이 실행되기 시작하면 메모리가 할당됩니다.) top 명령을 사용하여 프로그램의 메모리 사용을 확인할 수 있습니다.

주 3 : t가 전역이므로이 값만 유지되는 것이 중요합니다. 함수의 로컬 데이터 할당은 스택에서 런타임에 계속 발생합니다. 따라서 t이 로컬 인 경우 객체 파일은 7.3K 만 사용했을 것입니다.

참고 4 : 초기화 된 전역 변수와 마찬가지로 static 초기화 된 로컬 변수는 data 세그먼트에도 보관됩니다. A static 글로벌은 과 같음은 변수의 범위를 현재 파일로만 제한한다는 점을 제외하면 전역 변수와 같습니다.

+0

실행 파일 크기가 7.3K 인 경우에도 프로세스 크기는 여전히 130MB입니다. –

+0

@brianbeuning 아주 분명하지만 완전성을 위해 추가되었습니다. – axiom

+0

이것은 놀랍습니다. 저는 GCC로 상당한 크기의 배열을 중괄호로 초기화했지만 결코 그런 것을 보지 못했습니다. 비 균일 데이터 만이 실행 파일에 저장되고, 나머지는'memset' 같은 루프로 초기화됩니다. 어쩌면 이상한 최적화 또는 디버그 플래그를 사용하고 있을까요? – Damon

관련 문제