2013-06-22 1 views
10

저는 작은 소프트웨어 엔진을 설계하고 있습니다. 많은 수의 세트를 신속하게 반복 할 수 있도록 스택을 비싸게 사용하고 싶습니다. 그러나 스택이 힙만큼 큰 메모리 저장소가 아니기 때문에 이것은 나쁜 생각 일 수 있다는 것이 나에게 발생했다. 하지만 스택의 속도와 동적 할당 코딩 방법의 부족에 매료되었습니다.스택에서 사용 가능한 공간을 확인할 수 있습니까?

주어진 플랫폼에서 스택을 얼마나 멀리 밀어 낼 수 있는지 알아볼 방법이 있습니까? 주로 모바일 장치를 찾고 있지만 모든 플랫폼에서 문제가 발생할 수 있습니다.

+0

중복되지는 않지만 http://stackoverflow.com/q/1756285/1729885 –

+0

을 살펴보십시오. 따라서 스택 크기를 동적으로 (런타임에) 결정하고 싶습니까? – ComFreek

+0

나는 일반적인 해결책이 있다고 생각하지 않는다. 스택 크기는 스레드마다 다를 수 있습니다. –

답변

7

, getrlimit 사용

RLIMIT_STACK 
      The maximum size of the process stack, in bytes. Upon 
      reaching this limit, a SIGSEGV signal is generated. To handle 
      this signal, a process must employ an alternate signal stack 
      (sigaltstack(2)). 

를 Windows에서 VirtualQuery 사용

을 첫 번째 통화를 들면, 에 그것을 스택에 임의의 값의 주소를 전달하는 기반을 얻을 커밋 된 스택 공간의 주소 및 크기 (바이트). 스택이 아래쪽으로 커지는 x86 시스템에서베이스 주소와 VirtualQuery에서 다시 크기 을 뺍니다. 그러면 스택에 예약 된 공간의 크기가 이됩니다 (사용자가 이 스택 한계에 정확히 맞지 않는다고 가정 함). 크기). 두 개의 숫자를 합산하면 자연스럽게 총 스택 크기를 얻을 수 있습니다.

스택 크기가 구현 및 호스트 시스템에 논리적으로 남겨 지므로 논리적으로 플랫폼 독립적 인 방법은 없습니다. 내장형 미니 SOC에서는 128GB RAM 서버보다 배포 할 리소스가 적습니다. 그러나 모든 OS'es의 특정 스레드의 스택 크기와 API 관련 호출에 영향을 줄 수 있습니다.

1

언어 내에서 표준 방법이 없습니다. 나는 쿼리 할 수있는 문서화 된 확장 기능조차 모르고있다.

그러나 일부 컴파일러에는 스택 크기를 설정할 수있는 옵션이 있습니다. 또한 플랫폼은 프로세스를 시작할 때 수행 할 작업을 지정하거나 새 스레드의 스택 크기를 설정하거나 기존 스레드를 조작 할 수있는 방법을 제공 할 수 있습니다.

작은 플랫폼의 경우 전체 메모리 크기를 알고 한쪽 끝에 모든 데이터 세그먼트가 있고 힙에 설정된 크기 영역 (0 일 수 있음)이 있고 나머지는 스택에서 접근하여 다른 쪽에서 접근합니다.

2

표준 C++에서는 분명히 그렇지 않습니다. 휴대용 방식으로, 아마도 아닙니다. 때때로 특정 OS에서. 그 밖의 것이 없다면 자신 만의 실행 파일 크기를 열고 실행 파일의 헤더를 검사하여 스택 크기를 확인할 수 있습니다. [다음 문제는 물론 "얼마나 많은 스택이이 코드보다 먼저 사용되었는지"입니다. 이는 결정하기가 어려울 수 있습니다. "

코드를 별도의 스레드에서 실행하는 경우 많은 (낮은 수준의) 스레드 인터페이스에서 스택 (또는 스택 크기)을 지정할 수 있습니다 (예 : pthread_set_stacksize 또는 MS _beginthread). 다시 말하지만 실제 스레드 코드에 도달하기 전에 얼마나 많은 공간이 사용되었는지 정확하게 알 수는 없지만 엄청난 양은 아닙니다.

물론 임베디드 시스템 (예 : 휴대 전화)에서 스택 크기는 일반적으로 매우 작습니다. 4K, 12K 또는 64KB는 매우 정상적입니다. 일부 시스템의 스택 크기보다 훨씬 작을 수도 있습니다.

또 다른 잠재적 인 문제점은 실제로 스택에 얼마나 많은 공간이 사용되는지를 알 수 없다는 것입니다. 컴파일 된 시스템에서 사실 이후에 측정 할 수 있습니다. 물론 스택 로컬 배열이 int array[25]; 인 경우, 우리는 그것이 적어도 25 * sizeof(int)을 차지한다는 것을 알 수 있습니다. 그러나 패딩이있을 수 있으며, 컴파일러는 레지스터 등을 스택에 저장합니다.

편집, 추가 고려 사항 : 나는 또한 많은 이점을 보지 못합니다. 두 코드 경로 :

if (enough_stack_space_for_something) 
     use_stack_based_algorithm(); 
else 
     use_heap_based_algorithm(); 

이렇게하면 상당한 양의 추가 오버 헤드 및 더 많은 코드는 일반적으로 임베디드/모바일 시스템에서 좋은 계획이 아닙니다.

Edit2 : 또한 메모리를 할당하는 것이 런타임의 주요 부분 인 경우, 예를 들어 블록 작성이 도움이 될 수있는 이유를 살펴볼 수 있습니다.

* nix에서 스크립트에
5

가능한 휴대용 솔루션은 할당자를 직접 작성하는 것입니다.
프로세스 스택을 사용할 필요없이 힙에서 시뮬레이션 만하면됩니다.
처음에는 많은 양의 메모리를 할당하고 할당하는 동안 스택 할당자를 쓰면 스택 할당자가 사용됩니다.
C++에서이를 달성하는 방법에 대한 정보는 Google '할당 자 요구 사항'을 참조하십시오.

'Stack Allocator'라는 용어가 표준형인지 확실하지 않지만 할당 또는 할당 취소가 발생해야하는 위치와 같은 스택을 스택에 넣어야한다는 의미는 아닙니다.
알고리즘이이 패턴에 맞다고 말했기 때문에 쉽습니다.

2

이식성이없는 이유에 대해 이미 설명한 답변을 확장하면 실제 스택의 전체 개념이 표준에 포함되지 않습니다. 함수 호출 레코드 이외의 다른 곳에서 스택을 사용하지 않는 C 또는 C++ 런타임을 작성할 수 있습니다 (내부적으로 링크 된 목록 또는 다른 것일 수 있음).

스택은 특정 컴퓨터/OS/컴파일러의 구현 세부 사항입니다. 따라서 스택 메트릭에 액세스하는 모든 기법은 시스템/OS/컴파일러에만 적용됩니다.

특정 질문에 대한 실제 답변이 아니라 (Niels는이를 잘 설명했지만) 문제 도메인에 대한 조언으로서 힙에 많은 양의 메모리를 할당하십시오. "실제"스택이 다른 점은 편의를 제외하고는 아무 이유도 없습니다. 대단히 재귀 적 (비 꼬리 재귀 적) 알고리즘은 사실상 무제한의 "스택"을 갖도록하기 위해 종종이를 수행해야합니다. 호스트 응용 프로그램을 손상시키는 대신 런타임 오류/예외를 제공하기를 원하는 스크립팅 언어도 종종 이렇게합니다. 효율적으로하려면 "split stack"(std::deque처럼)을 구현하거나 필요에 따라 충분히 큰 스택을 미리 할당 할 수 있습니다.

+0

_ "진짜"스택이 다른 점은 편의를 제외하고는 아무 이유도 없습니다.하지만 스택이 힙보다 빠르다는 것이 종종 언급됩니다. – johnbakers

+0

힙에서 _Allocations_ ('malloc' 또는'new' 등을 사용)는 스택에 로컬 변수를 생성하거나 alloca와 같은 것을 사용하는 것보다 느립니다. 스택은 대개 자동으로 조각화 및 캐시 위치 문제를 피하는데, 이는 순진 할 때 힙 사용을 방해 할 수 있지만주의 할 경우에는 문제가되지 않습니다. 일부 아키텍처에는 스택 구현을위한 명시적인 지침이 있습니다 (예 : x86에''push ''pop '하지만, 대부분의 알고리즘에서 그 이점은 극히 미미할 것이다. 필요한 성능 수치가 없다면 걱정할 필요가 없습니다. –

관련 문제