문제

나는 현재 작업에 대한 프로젝트 의 이미지 처리 필요로 하는 엄청난 양의 메모리입니다.거기에 아무것도 할 수 있을 피하는 힙 조각과에 대한 액세스 속도를 높이기 위해 이미지 데이터가 있는 이미 로딩되었으로 메모리가 있습니까?

응용 프로그램에 기록되어있는 C++및 Windows XP 에서 실행 됩니다.

편집: 응용 프로그램 일부 전처리와 이미지 데이터 포맷을 계산하는 모습이크업-테이블,추출 sub 이미지의 관심을...응용 프로그램이 필요한 약 2GB RAM 처리하는 동안,의 약 1.5GB 사용할 수 있습에 대한 이미지 데이터입니다.

도움이 되었습니까?

해결책

을 하는 경우 의 이미지 처리 가능성이 있는 할당하는 큰 블록에서 시간(512x512,2-바이트는 픽셀당 이미지).조각 물린 것입니다 당신이 경우에 당신은 작은 객체를 할당 의 할당 이미지 버퍼입니다.

쓰 사용자 정의 할당자는 반드시 하이 특정 사용한 경우.당신이 사용할 수 있는 표준 C++할당자를 위한 당신의 이미지 개체하지만,픽셀 버퍼로 사용할 수 있는 사용자 정의 할당하는 모든 관리에 당신의 이미지 개체입니다.여기에 빠르고 더러운 윤곽:

  • 사용하는 구조체의 정적 배열,각각의 구조체:
    • 솔리드 메모리를 보유할 수 있는 N--이미지 chunking 을 제어하는 데 도움이 조각을 처음 N 의 5 도
    • 병렬 배열의 bools 는지 여부를 나타내는 해당 이미지가 사용
  • 를 할당 배열을 검색에 대한 빈 버퍼 설정 플래그
    • 지 않으면 발견되,추가로 새로운 구조체를 배열의 끝
  • 을 할당을 찾은 해당하는 버퍼에 array(s)고 명확한 boolean flag

이것은 단지 하나의 간단한 아이디어를위한 공간을 많이 변형입니다.중요한 요령을 피하기 위해 해방 및 재할당의 이미지 픽셀 버퍼입니다.

다른 팁

답이 있지만 문제의 세부 사항을 모르면 일반적인 것이 어렵습니다.

32 비트 Windows XP를 가정합니다.

100 MB의 인접한 메모리가 필요하지 않도록하십시오. 운이 좋지 않으면 몇 가지 임의의 DLL이 사용 가능한 주소 공간을 통해 불량 지점에 자신을로드하여 매우 넓은 영역의 연속 메모리를 빠르게 절단합니다. 필요한 API에 따라 예방하기가 어려울 수 있습니다. 몇 가지 '정상적인'메모리 사용 외에도 400MB 블록의 메모리를 할당하면 최종 '작은'40MB 블록을 할당 할 수있는 곳이없는 방법은 놀라운 일이 될 수 있습니다.

반면에, 한 번에 합리적인 크기의 덩어리를 prealloced하십시오. 10MB 정도의 순서는 좋은 타협 블록 크기입니다. 데이터를 이러한 종류의 크기 청크로 분할 할 수 있다면 주소 공간을 합리적으로 효율적으로 채울 수 있습니다.

여전히 주소 공간이 부족한 경우, 일종의 캐싱 알고리즘을 기반으로 블록을 출입 할 수 있어야합니다. 페이지 아웃에 올바른 블록을 선택하는 것은 처리 Algortihm에 크게 의존 할 것이며 신중한 분석이 필요합니다.

물건을 페이지로 가져갈 위치를 선택하는 것은 또 다른 결정입니다. 임시 파일에 작성하기로 결정할 수 있습니다. Microsoft의 주소 창문 연장 API를 조사 할 수도 있습니다. 두 경우 모두 애플리케이션 디자인에주의를 기울여야합니다. 그렇지 않으면 실제로 나쁜 일 (TM)이 발생할 것입니다.

행운을 빕니다!

큰 이미지 매트릭스에서 작업을 수행하려는 경우 "타일링"이라는 기술을 고려할 수 있습니다. 아이디어는 일반적으로 이미지를 메모리에로드하여 동일한 연속 바이트 블록에 한 줄에 픽셀이 아니라 2D 공간의 정사각형이 아니라는 것입니다. 이에 대한 근거는 하나의 스캔 라인이 아닌 2D로 서로 더 가까운 더 많은 작업을 수행한다는 것입니다.

이것은 메모리 사용을 줄이지 않지만 페이지 교환 및 성능에 큰 영향을 줄 수 있습니다.

문제 (예 : 언어)에 대한 더 많은 정보가 없으면 할당을 재사용하여 할당이 발생하지 않고 할당, 운영 및 자유롭지 않은 할당을 피하는 것입니다. 다음과 같은 할당 자 dlmalloc Win32 힙보다 조각화를 더 잘 처리합니다.

여기서 타격 할 것은 가상 주소 범위 제한이며, 32B Windows는 최대 2GB를 제공합니다. 또한 DirectX 또는 OpenGL과 같은 그래픽 API를 사용하면 프레임 버퍼, 텍스처 및 유사한 데이터에 2GB의 광범위한 부분을 사용한다는 것을 알고 있어야합니다.

32B 응용 프로그램의 경우 1.5-2 GB는 달성하기가 어렵습니다. 이를 수행하는 가장 우아한 방법은 64B OS 및 64B 응용 프로그램을 사용하는 것입니다. 64B OS 및 32B 응용 프로그램에서도 사용하는 한 다소 실행 가능할 수 있습니다. LARGE_ADDRESS_AWARE.

그러나 이미지 데이터를 저장해야하므로 사용 하여이 문제를 해결할 수도 있습니다. 메모리 스토어로서 파일 매핑 - 이것은 메모리가 커밋되고 액세스 할 수있는 방식으로 수행 할 수 있지만 가상 주소를 전혀 사용하지는 않습니다.

당신이 의미하는 것이 여기에 추측합니다 조각화를 피하십시오 그리고 아닙니다 탈퇴를 피하십시오. 또한 비 관리 언어 (C 또는 C ++)로 작업하고 있다고 추측합니다. 나는 당신이 큰 메모리 덩어리를 할당 한 다음 할당 된 메모리 블록에서 힙 할당을 제공 할 것을 제안합니다. 이 메모리 풀에는 큰 메모리 블록이 포함되어 있기 때문에 단편화가 덜 발생합니다. 요약하려면 사용자 정의 메모리 할당자를 구현해야합니다.

이것에 대한 몇 가지 일반적인 아이디어를 참조하십시오 여기.

관리되는 플랫폼에서 시스템 (쓰레기 수집기)이 조각화를 처리하기 때문에 관리하지 않는 것을 사용하고 있습니다.

C/C ++의 경우 기본값보다 다른 할당자를 사용할 수 있습니다. (StackowerFlow에 할당 자에 대한 일부 스레드가있었습니다).

또한 자체 데이터 저장소를 만들 수 있습니다. 예를 들어, 현재 진행중인 프로젝트에서는 비트 맵을위한 사용자 정의 저장소 (Pool)가 있습니다 (우리는 많은 연속 메모리 덩어리에 저장). 조각화가 크면 파편화 및 해체됩니다.

수동 메모리 관리를 구현해야 할 수도 있습니다. 이미지 데이터가 오래 살았습니까? 그렇지 않은 경우 Apache Web Server에서 사용하는 패턴을 사용할 수 있습니다. 많은 양의 메모리를 할당하여 메모리 풀에 랩핑 할 수 있습니다. 수영장을 기능의 마지막 인수로 전달하여 수영장을 사용하여 임시 메모리를 할당 할 필요성을 충족시킬 수 있습니다. 통화 체인이 완료되면 풀의 모든 메모리를 더 이상 사용하지 않아야하므로 메모리 영역을 문지르고 다시 사용할 수 있습니다. 할당은 빠릅니다. 포인터에 값을 추가하는 것을 의미하기 때문입니다. 거래는 매우 빠릅니다. 한 번에 매우 큰 메모리 블록을 해제하기 때문입니다.

응용 프로그램이 멀티 스레드 인 경우 스레드 커뮤니케이션 오버 헤드를 피하기 위해 풀을 스레드 로컬 스토리지에 보관해야 할 수도 있습니다.

면 격리시킬 수 있습니다 정확히 그 장소는 당신을 가능성이 큰 블록 할당할 수 있습니다(Windows 의 경우)직접 전화 VirtualAlloc 대신 것을 통해서 메모리 관리자입니다.를 이용하여 단편화 내에서의 일반 메모리 관리자입니다.

이 솔루션을 필요로하지 않을 사용하는 사용자 정의 메모리 관리자입니다.

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