2013-07-18 1 views
0

많은 양의 계산 된 데이터를 저장하고 있으며 현재 필요한 다량 유형을 줄이기 위해 다형성 유형을 사용하고 있습니다. 작업이 끝나면 개체를 삭제하는 것 외에는 모든 것이 매우 빠릅니다. 더 나은 대안이 있어야한다고 생각합니다. 코드는 각 단계에서 상태를 계산하고 현재 조건에 따라 특정 값을 저장해야합니다. 최악의 경우는 전체 객체 상태를 저장하는 것이고 최상의 상태는 거의 아무것도 저장하지 않습니다.다형성 데이터 저장소 대체 방법

class BaseClass 
{ 
public: 
    virtual ~BaseClass() { } 

double time; 
    unsigned int section; 
}; 

class VirtualSmall : public BaseClass 
{ 
public: 
    double values[2]; 
    int othervalue; 
}; 

class VirtualBig : public BaseClass 
{ 
public: 
    double values[16]; 
    int othervalues[5]; 
}; 

... 

std::vector<BaseClass*> results(10000); 

적절한 객체 유형이 연산 중에 발생하고 포인터가 벡터에 저장된 다음과 같다 : (매우 단순화) 설치된다. vtable + 포인터의 오버 헤드는 크기가 가장 큰 개체와 가장 작은 개체 (크기에 따라 최소 200 바이트) 간의 크기 차이보다 훨씬 작습니다. 종종 가장 작은 객체가 가장 큰 객체 대신 사용될 수 있고 잠재적으로 수천만 개의 객체가 저장되기 때문에 몇 기가 바이트의 메모리 사용량을 절약 할 수 있습니다. 그런 다음 기본 클래스에 올바른 항목을 찾기 위해 필요한 정보가 들어 있기 때문에 결과를 매우 빠르게 검색 할 수 있습니다. 그런 다음 실제 유형으로 dynamic_cast를 다시 올릴 수 있습니다. 대부분의 경우 잘 작동합니다.

유일한 문제는 삭제입니다. 수천만 개의 개체가있는 경우 모든 메모리를 해제하는 데 몇 초가 걸립니다. 삭제 코드는 각 객체를 반복하고 가상 소멸자를 호출하는 delete results[i]을 반복합니다. 주위를 해결하는 것이 불가능하지는 않지만보다 우아한 해결책이 있어야한다고 생각합니다.

큰 연속 메모리 블록 (malloc 또는 유사)을 할당하여 트랙을 유지 한 다음 블록 내부의 다음 빈 메모리 배치에 올바른 포인터를 생성 할 수 있습니다. 그 포인터는 벡터에 저장됩니다. 메모리를 확보하기 위해서 작은 블록의 큰 블록은 free()를 호출해야합니다. vtable은 더 이상 존재하지 않으며 올바른 캐스팅을 보장하기 위해 더 작은 유형 필드로 대체 될 수 있습니다. 따라서 공간도 절약됩니다. 그것은 매우 C 스타일의 솔루션이지만 특히 좋지는 않습니다.

제가 간과하고있는 이런 유형의 문제에 대한 C++ 스타일의 해결책이 있습니까?

+0

정확히 어떤 종류의 데이터입니까? 모든 것이 사소한 destructable pod입니까? – Yakk

+0

예, 단순한 데이터입니다. 유일한 기능은 가상 소멸자입니다. – Kyle

+0

할당자는 C++ 스타일 솔루션입니다. 메모리 풀 –

답변

1

클래스에 대해 "new"연산자 (즉, void * VirtualSmall :: operator new (size_t))를 오버로드하여 사용자 정의 할당 자에서 메모리를 확보하도록 구현할 수 있습니다. 각 파생 된 클래스에 하나의 블록 할당자를 사용하여 각 블록 크기가 클래스의 배수가되도록 저장합니다.

정리가 끝나면 각 할당자가 모든 블록을 해제하도록합니다. 소멸자는 호출되지 않으므로 필요하지 않은지 확인하십시오.

+0

확실히 더 많은 C++ 스타일로 메모리 정렬 문제를 제시하고 할당 된 트랙을 유지합니다. 어딘가에 메모리 덩어리. 고마워요. 조금 더 읽어 보겠습니다. – Kyle

+0

각 블록은 쌍과 같습니다. 정수는 사용중인 elemnts 수를 추적합니다. 할당 자 자체는 이러한 쌍의 벡터와 하나 또는 두 개의 작은 편의 함수를 사용하여 쉽게 구현할 수 있습니다. SomeLargeStorage를 특정 유형의 배열을 포함하는 enum으로 정의 할 수 있습니다. 이렇게하면 컴파일러가 올바르게 정렬되는지 확인할 수 있습니다. – DanielKO

+0

또한, 나는 (아마도) 최적의 솔루션이 어떻게 생겼는지 말하는 것과 같은 것을 구현하도록 제안하지 않습니다. HeapLayers/Hoard (http://www.hoard.org)에서 블록 할당자가 사용할 준비가되어 있는지 확인하십시오. – DanielKO

관련 문제