문제

내가 찾는 것에 대한 아이디어에 대한 힙 관리를 처리하는 매우 특정 상황:많은 아주 작은 할당,에 이르기까지 12~64 바이트로 각.큰 아무것도,나이에 전달하는 일반 힙-관리자,그래서 작은 블록이 필요한 음식을 장만한다.단지 4 바이트의 정렬이 필요합니다.

나의 주요 관심사는

  1. 오버헤드가 발생합니다.일반 libc 힙 일반적으로 라운드까지 할당하여 다중 16 바이트의한 다음,다른 추가한 16 바이트는 헤더 이미 50%이상 오버헤드에서 20-byte 할당,니다.
  2. 성능

중 하나 도움이 되는 Lua(사용자의 이 힙)을 말할 것이다 당신의 크기록의 확보를 호출할 때는 무료()-이할 수 있도록 특정 최적화되어 있습니다.

나는 나의 현재에 접근,작동하는지 확인하고 싶을 개선하에 그것은 모든 가능한 경우.어떤 아이디어가?

도움이 되었습니까?

해결책

모두 같은 크기의 객체에 매우 효율적인 힙 관리자를 구축 할 수 있습니다. 필요한 각 크기의 객체에 대해이 힙 중 하나를 만들거나 약간의 공간을 사용하지 않으면 16 바이트 객체, 32, 64에 하나를 만들 수 있습니다. 33 바이트 할당에 대한 31 바이트 (64 블록 크기 힙에 들어갑니다).

다른 팁

에 확장하기 위하여 무엇을 그렉 Hewgill 말한다,한 가지 방법은 매우 효율적인 고정 크기의 힙입니다:

  1. 분 큰 버퍼로 노드입니다.노드 크기 이상이어야 합 sizeof(void*).
  2. 들을 함께 문자열로 단독으로 연결된 목록(무료로"list"),사용하는 첫 번째 sizeof(void*)각각의 바이트는 무료로 사용되는 노드 링크를 포인터이다.에 할당된 노드가 필요하지 않습니다 링크를 포인터,그래서 당 노드 오버헤드은 0 입니다.
  3. 할당을 제거하여 머리의 목록을 반환(2 부,1 점)
  4. 무료 삽입하여 머리 목록(1 부,2 점).

분명히 3 단계 또는지 확인하려면 목록의 빈면 그렇게 무리한 작업의 새로운 큰 버퍼(또는 실패).

더 효율적으로 그렉 D hazzen 말을 할당하여 증가 또는 감소시키는 포인터(1 로드,1 개의 상점),과하지 않는 방법을 제공하는 단일 노드에 모두.

편집:두 경우 모두에서,무료 처리할 수 있으로 합병증이"아무 것도 더 큰 저 전달 일반에 힙-manager"에 의해 도움이 되는 사실이 당신의 크기에 다시 호출하는 무료입니다.그렇지 않으면 당신은 것 하나에서 찾고있는 플래그(오버헤드를 아는 4 바이트당 노드)또는 다른 조회에서는 어떤 종류의 기록의 버퍼(s)당신이 사용됩니다.

대답은이 객체의 수명 패턴에 따라 다를 수 있습니다. 진행할 때 물체가 모두 인스턴스화 된 다음 모두 한 번에 제거 된 경우, 단순히 포인터를 증가시켜 메모리를 할당하는 매우 간단한 힙 관리자를 만드는 것이 합리적 일 수 있습니다. 그런 다음 완료되면 전체 더미를 날려 버리십시오.

Raymond Chen이 만들었습니다 흥미로운 게시물 그것은 당신에게 영감을주는 데 도움이 될 수 있습니다. :)

나는 OneByones 대답을 좋아합니다.

당신은 또한 고려할 수도 있습니다 버디 시스템 고정 크기 힙 세트.

다음 할당 라운드로 넘어 가기 전에 많은 메모리가 할당, 사용 및 해제되면 가능한 가장 간단한 할당자를 사용하는 것이 좋습니다.

typedef struct _allocator {
    void* buffer;
    int start;
    int max;
} allocator;

void init_allocator(size_t size, allocator* alloc) {
    alloc->buffer = malloc(size);
    alloc->start = 0;
    alloc->max = size;
}

void* allocator_malloc(allocator* alloc, size_t amount) {
    if (alloc->max - alloc->start < 0) return NULL;
    void* mem = alloc->buffer + alloc->start;
    alloc->start += bytes;
    return mem;
}

void allocator_free(allocator* alloc) {
    alloc->start = 0;
}

내가 사용하는 대부분 O(1)는 작은 블록의 메모리 관리자(SBMM).기본적으로 그것이 방식으로 작동:

1)할당 큰 수퍼에서는 OS 와 트랙을 시작+끝 주소를 범위로.은 크기의 파일이나 디렉 조절 가능하지만 1MB 은 매우 좋은 크기입니다.

2)수퍼으로 깨진 블록(도 조절기...4K-64K 좋에 따라서 응용 프로그램).이러한 각 블록을 처리 할당을 의 특정 크기와 저장하는 모든 항목에서 Block 으로 단독으로 연결된 목록입니다.할 때 할당할 수퍼,당신은 연결 목록의 블록입니다.

3)할당 항목을 의미하는)확인을 볼 수 있으면 블록으로 무료로 항목을 처리하는 크기하지 않을 경우,할당하는 새로운 블록에서 수퍼.B)항목을 제거하거 블록에서의 무료 목록입니다.

4)해방하여 항목을 주는 의미)찾는 슈퍼블록을 포함하는 주소로(*)B)찾는 블록에서 파일이나 디렉(빼기 수퍼 시작 주소와 분할하여 블록 크기)C)를 밀어 다시 항목에서 Block 의 무료 품목 목록입니다.

에 명시된 바와 같이,이 SBMM 은 매우 빠르게 실행되 O(1)성능(*).버전에서 나는 구현 시 사용 AtomicSList(비슷한 SLIST Windows)되지 않도록 만 O(1)성능을 가지고 있지만 또한다면 및 LockFree 에서 구현됩니다.당신은 실제로 구현하는 알고리즘을 사용하여 Win32SLIST 는 경우.

흥미롭게도,알고리즘을 할당하기 위한 블록에서 수퍼 또는 항목에서 블록 결과에 거의 identicaly 코드(그들 모두 O(1)할당 off 무료 목록).

(*)는 수퍼는 배치에서 rangemap O(1)평균 이하의 성능(지만 잠재적인 O(Lg N)worstcase N 의 수입니다 수퍼).의 폭 rangemap 에 따라 달라집을 아는 대략 얼마나 많은 메모리를 당신이해야 할 것을 얻기 위해 O(1)성능입니다.는 경우 오버슈트,당신은 폐기물의 비트 메모리이지만 여전히 O(1)성능입니다.는 경우 미달,당신은 접근 방식 O(Lg N)능지만 N 에 대한 수퍼 count--지 않은 항목을 계산합니다.이후 파일이나 디렉산에 비해 매우 낮은 품목 count(약 20 바이너리 배에 코드),이게 중요하지 않습의 할당자.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top