2013-02-26 3 views
3

저는 여러 번 호출하는 함수가 작지만 동적 크기의 벡터를 만드는 C++의 사용 시나리오를 가지고 있습니다. 내 프로그램을 프로파일 링 한 후, std :: vector :: free()에서 지나치게 많은 시간을 보냈다. 이러한 문제에 대한 자연스러운 (C++ - esque) 솔루션은 기본 할당자를 내 사용 시나리오에 좀 더 동의 할 수있는 것으로 전환하는 것처럼 보였습니다. 특히 메모리 풀 전략을 사용하는 것이 여기에서 의미가있는 것처럼 보였습니다. 그러나 boost :: pool_alloc은 지금까지 아무런 문제가되지 않았습니다. 나는 그것을 작동 시키려고했지만 할당은 작은 반면, 함수는 f()라고 부르는 작은 함수에서는 더 빠르지 만 f()를 호출하는 함수는 으로 돌아 오기 전에 멈춘다. 아주 오랜 시간이..boost :: pool 외에도 C++에서 사용자 정의 풀링 된 allocator

더 많은 프로파일 링은 pool_allocator :: ordered_free()에서 모든 시간 (문자 그대로 수십 분이 지났기 때문에 기다리는 것에 지쳐 버렸습니다)이 소비되었음을 보여줍니다. 간단한 테스트 프로그램에서이 같은 동작을 (극단적 인 것은 아니지만) 재현했는데 실제로 많은 수의 생성 된 벡터가 메모리를 싱글 톤 풀로 반환하면 함수는 반환되기 전에 아주 오랫동안 정지됩니다 .

누군가이 동작을 피하는 방법을 알고 있거나 그러한 문제가없는 다른 C++ 풀 할당자를 알고 있다면 나는 많은 의무를지게 될 것입니다!

+0

'예약'은 올바르게 도움이 될 수 있습니다 (아직없는 경우). – justin

+1

안녕 저스틴, 네, 이미 벡터를 예약하고 있습니다. 문제는 함수 호출시 각 벡터의 크기를 알 수 있다는 것입니다.그들은 성장하지 않고 있습니다), 컴파일 시간이 아니기 때문에 여전히 동적입니다. – nomad

답변

0

일단 모든 것이 다가 오면 할당 및 해제가 빠른 속도로 진행되는 몇 시간을 직접 작성했습니다. 1. 크기별로 풀 맵을 만듭니다. 2. 각 풀에는 이중 연결 목록이 있습니다. 3. 각 블록에는 목록 노드와 소유자 풀 참조, 크기 검사 등을 위해 앞뒤에 여분의 공간이 있습니다. 4. 블록 크기보다 큰 첫 번째 풀을 찾아야하므로 할당이 빠릅니다. 첫 번째 항목을 unlist하십시오. 5. 할당 해제는 메모리 블록에서 바로 풀에 대한 포인터가 있기 때문에 빠릅니다. 따라서 다시 할당하면됩니다. 6. 시작할 때 빈 풀을 만들 수 있습니다. 그런 다음 각 alloc에 ​​대해 먼저 풀에서 목록을 제거합니다. 실패하면 malloc()을 대신 사용하십시오. 블록이 해제되면이를 풀지 않고 풀에 다시 추가하십시오. 7. 앱이 안정적으로 실행되면 모든 할당이 풀링 된 풀 목록에서 곧바로 나오며 자유가 곧 다시 돌아옵니다. 8. 프로그램이 종료되면 풀의 모든 메모리를 Free()로 설정하십시오.

질문에서
0

, 내가

  • 그것은 벡터의 크기는 제한되어 해당 하나 개의 함수
  • 의 가정
  • 이 기능이 너무 자주 반복적으로
  • 을 호출되지 않습니다 (당신은 작은 말할)

동적 할당 메모리 대신 스택 할당 메모리를 사용하는 경우를 고려하십시오. 벡터를 사용하지 않고 std::array<>과 일부 크기 표시기 (저장된 유형이 많이 구성 가능한 경우) 또는 고정 크기 및 배치의 새 원시 메모리 버퍼를 사용하거나 할당 자 클래스로 벡터를 사용하여 벡터를 해당 할당 자와 함께 사용하여이 작업을 수행 할 수 있습니다 수업.

성능 문제가 이러한 작은 코드 영역에 국한되어 있다면 boost :: pool과 같은 일반적인 목적의 메모리 관리 도구를 사용하지 않지만 현재 상황에 매우 특화된 것을 롤업합니다.

+0

안녕하세요. 저장된 타입은 쉽게 구성 할 수 있습니다 (size_t). 그러나 시나리오를 처음에 보냈던 것보다 조금 더 복잡하기 때문에 스택 할당 스토리지를 실제로 사용할 수는 없습니다. 특히 많은 수의 벡터가 각 함수 호출 내에서 생성되지만 함수가 반환되기 전에 대부분이 파괴되지만 소수의 함수는 다른 힙 객체에 통합되어 함수를 벗어납니다. 나는 그 벡터들을 복사 할 수 있다고 생각한다. 내 * 할당자를 쓰는 것을 피하고 싶었지만 이것이 최선의 방법 일 수 있습니다. – nomad

+0

어떤 벡터가 힙 객체로 이동되는지 미리 아는 경우에는 표준 할당자를 사용할 수 있습니다. –