2011-08-11 2 views
2

주어진 시간에 스택 프레임이 더 자주 할당 해제되기 때문에 주어진 시간에 메모리에서 더 적은 변수가 있기 때문에 C에서 하나의 큰 함수보다 더 효율적인 메모리로 작업을 5 개의 함수로 나눕니 까? 그것은 컴파일러와 최적화에 의존 하는가? 그렇다면 어떤 컴파일러가 더 빠릅니까?변수가 더 자주 할당 해제되기 때문에 일반적으로 더 작은 함수를 메모리 효율적으로 만드십니까?

지역 변수가 많고 스택 프레임이 중앙의 메인에서 나오며 서로 겹쳐서 생성되지 않는다고 대답하십시오.

필자는이 기능을 작은 기능으로 분해하는 다른 장점을 알고 있습니다. 메모리 사용과 관련하여이 질문에 답하십시오.

+0

메모리를 최소화하기 위해 코드를 구성하지 마십시오. 가장 이해하기 쉬운 방법으로 이해하고 이해하기 쉽습니다. 마이크로 최적화는 시간 낭비입니다. –

+1

컴퓨터가 1970 년에 만들어 졌습니까? [PDP11] (http://en.wikipedia.org/wiki/PDP-11_architecture)와 같은 제한된 아키텍처입니까? –

+0

아니요, 더 쉽게 읽을 수 있다면 더 효율적입니다. 프로그래머는 컴퓨터 메모리보다 훨씬 비쌉니다. –

답변

2

그것은 프로그램에 대한 스택 사용의 "높은 물 마크"를 줄이고, 수 프로그램의 전체 메모리 요구 사항을 줄일 수 있도록 경우.

예, 최적화에 따라 다릅니다. 옵티마이 저가 함수 호출을 인라인하면 모든 인라인 함수의 모든 변수가 하나의 큰 스택 프레임으로 래핑된다는 것을 알게 될 것입니다. 사용할 가치가있는 컴파일러는 [*] 인라이닝이 가능하므로 컴파일러에 의존하지 않습니다. 정확히 그것이 일어날 때, 다를 것입니다.

로컬 변수가 작 으면 시작시 자동으로 할당 된 것보다 더 많은 스택을 프로그램에서 사용하는 것이 거의 없습니다. 처음에받은 것을 지나치 지 않으면 않는 한, 전체 메모리 요구 사항에 아무런 차이가 없습니다.

스택에 여러 개의 큰 구조체 (여러 킬로바이트)를 넣거나 킬로바이트가 많은 메모리 인 컴퓨터를 사용하는 경우 전체 메모리 사용량에 차이가 발생할 수 있습니다. 따라서, "많은 지역 변수"에 의해 수십 개의 int과 포인터가 있으면 아무런 의미가 없습니다. "많은 지역 변수"에 의해 10k 버퍼가 수십 개 또는 함수가 매우 깊어서 수십 개의 레벨이 수백 개가되는 경우 int의 경우에는 가능한 한 최소한의 차이가있을 수 있습니다. OS 및 구성에 따라 다릅니다.

스택과 힙이 일반 RAM을 통해 서로 성장하고 중간의 여유 메모리가 둘 중 하나에 의해 동등하게 사용될 수있는 모델은 더 이상 사용되지 않습니다. 매우 제한된 시스템을 제외하고는 메모리 모델이 더 이상 그런 방식으로 설계되지 않았습니다. 현대 OS에서는 소위 "가상 메모리"가 있으며 스택 공간은 한 번에 한 페이지 씩 프로그램에 할당됩니다. 그들 중 대부분은 사용되는 스택의 페이지를 일반적으로 매우 큰 구성 한계까지 자동으로 할당합니다. 일부는 자동으로 스택을 확장하지 않습니다. 심비안은 최근에 사용했는데 몇 년 전 이었지만 심비안은 "현대"OS가 아닙니다. 임베디드 OS를 사용하는 경우 설명서에서 스택에 대해 말한 내용을 확인하십시오.

어느 쪽이든, 총 메모리 사용량에 영향을주는 것은 한 번에 얼마나 많은 스택 페이지가 필요한지입니다. 시스템이 스택을 자동으로 확장하면 사용중인 용량을 알지조차 모릅니다. 그렇지 않은 경우, 프로그램에 최고 수위 표시를 위해 충분한 스택이 제공되어야하며, 과도한 스택 사용을 감지 할 수 있어야합니다. 간단히 말해서, 이것은 이론적으로 차이를 만드는 것들 중 하나이지만, 실제로 차이는 거의 중요하지 않습니다. 프로그램이 실행되는 환경의 리소스에 비해 스택의 방대한 양을 사용하는 경우에만 중요합니다.

[*] 기본적으로 최적화되지 않은 어셈블러 인 C 컴파일러를 사용하여 PIC 등을 위해 C에서 프로그래밍하는 사람들 , 나는 그들의 컴파일러를 "사용 가치가 없다"고 불쾌감을 느낄 수있다. 이러한 장치의 스택은 "일반적인"시스템과 크게 다르므로 응답이 다릅니다.

1

대부분의 경우 스택에 할당 된 메모리 영역은 전체 프로그램에 대해 일정하다고 생각합니다. 사용량이 은 호출 스택의 깊이에 따라 달라지며 사용되는 변수가 적을수록 그 양은 적어집니다 (그러나 함수 호출은 반환 주소와 스택 포인터도 밀어 넣습니다).

또한 함수 호출 방식에 따라 다릅니다. 예를 들어, 두 함수가 연속적으로 호출되고 첫 번째 스택이 두 번째 호출 전에 팝되면 스택의 크기는 줄어 듭니다.하지만 첫 번째 함수가 두 번째 함수를 호출하면 스택이 적어집니다. 하나의 커다란 함수 (플러스 함수 호출 오버 헤드)를 가지고 있던 곳으로 돌아 간다.

0

그래, 제트 비행기에서 더 미세한 페인트 칠을 사용하면 공기 역학적 특성이 증가한다는 점에서 동일한 맥락에서 그렇습니다. 좋아, 그건 나쁜 비유이지만 요점은 물건을 분명하고 전신으로 만들거나 더 많은 기능을 사용하려고하는 문제가 있다면 전신을 사용하는 것입니다. 초보자가 서브 루틴이나 기능을 너무 많이 제공하는 경향이 있기 때문에 대부분의 경우 이러한 기능은 상호 배타적 인 것이 아닙니다.

메모리의 관점에서 볼 때 실제로 작업 (f, g, h)을 나누면 사용할 수있는 메모리 사용량이 약간 늘어나는 것을 볼 수 있지만 상호 의존성이 있다면 그렇게하지 않을 것이라고 생각합니다.

@ Joeel Burget이 말한 것처럼, 메모리 관리는 코드 구조화에서 실제로 고려 사항이 아닙니다.

그냥 받아주세요.

0

스택에 메모리 할당이 없습니다. 스택 포인터를 다음 값으로 이동하는 것뿐입니다. 스택 크기 자체는 미리 정의되어 있습니다. 따라서 메모리 사용량에는 차이가 없습니다 (스택 오버플로가 발생하는 상황).

+0

스택 포인터를 위로 움직이면 더 많은 메모리를 사용합니다. 스택과 힙은 서로를 향해 성장합니다. 더 많은 스택 공간 또는 힙 공간을 사용한다는 것은 기본적으로 같은 의미입니다. 여유 메모리가 적습니다. – theRealWorld

+0

글쎄, 페이지는 물리적으로 사용되지 않지만 예약되어 시스템 커밋 제한에서 차감됩니다. afaik – Oleg

0

거대한 기능을 작은 것으로 나누면 이점이 있지만 그 중 은 잠재적으로 더 많이 최적화 된 메모리 사용입니다.

말하기,이 기능이 있습니다.

void huge_func(int input) { 
    char a[1024]; 
    char b[1024]; 
    // do something with input and a 
    // do something with input and b 
} 

그리고 두 개로 나눕니다.

void func_a(int input) { 
    char a[1024]; 
    // do something with input and a 
} 

void func_b(int input) { 
    char b[1024]; 
    // do something with input and b 
} 

huge_func 메모리가 적어도 2048 바이트를 취할 것입니다 호출 한 다음 func_a를 호출 func_b 절반 정도 적은 메모리와 같은 결과를 얻을 수있다. 그러나 func_a 내부에 func_b을 호출하면 사용되는 메모리 양이 huge_func과 거의 같습니다. 본질적으로, @ sje397이 쓴 것.

이 말을 잘못하고 있지만 스택 메모리 사용을 줄이는 데 도움이되는 컴파일러 최적화가 없다고 생각합니다. 스택 메모리의 레이아웃은 사용 여부와 관계없이 모든 선언 된 변수에 대해 충분한 메모리가 예약되어야한다고 생각합니다.

관련 문제