yuchi's Development Home


유져모드 메모리 페이징 구현

조회 수 3383 추천 수 138 2007.09.23 02:59:01
라이트맵을 빌드할때는 어쨌거나 각 텍셀에 대한 3차원 좌표와 노멀값을 저장해놓고 있어야한다.

해보신 분은 아시겠지만 이게 용량이 만만치가 않다. 맵이 한 2km*2km쯤 되어도 진짜 살인적이다.

하여간 이놈이 메모리를 많이 쳐먹기 때문에 임시파일로 저장해놓고 라이트맵 빌드할때마다 디스크에서 읽어와서 계산하게 할 생각이었다.

근데 해보니 대부분의 상황에선 또 그렇게까지 치명적으로(어디까지나 상대적으로) 메모리를 많이 먹는건 아니었다.

뭣보다도...위대한 NT커널이 페이징을 훌륭하게 해주기 때문에 내가 굳이 하드디스크에 스왑시켜주지 않아도 그냥 메모리에 올려놓으면 알아서 페이징이 될터.

해서 빌드 한번 하면 엔진 내려갈때까지(툴이 종료될때 엔진도 종료시키니까) 라이트맵 패치 데이타를 메모리에 유지시키도록 했다.

그런데 얼마전에 노트북에서 테스트 하던 중 의외의 복병을 만났다.

그 라이트맵 패치 빌드하는 과정에서 메모리 할당에 실패한 것이다.

1기가 가까운 용량을 요구하긴 했지만..뭐 노트북도 메모리 2기가 꽂혀있는데? 할당에 실패할리가?

아차차. 생각해보니, 집이나 회사에서 쓰는 데스크탑은 64비트 머신에 , 64비트 os다.

64비트 프로세스와 32비트 프로세스의 어드레스 영역의 차이는 대우주와 개구리 살고 있는 연못의 차이랄까.

역시 메모리를 적게 쓰는 소프트가 잘 돌아갈 가능성이 높은 소프트웨어다.

해서 패치 생성,유지는 디스크에 스왑할 수 있도록 고치기로 하고 오늘(아니 어제군.새벽이니) 코드를 뜯어봤다.


라이트맵 코드에 페이징 코드를 막바로 넣는 것은 좀 그렇고...지저분해.

흠..뭔가 좀 우아하게 할 순 없을까. 이번에 짠 코드를 두고두고 재활용 할 수는 없을까.

그래. 범용적으로 쓸 수 있는 메모리 풀을 만들자. 페이징 기능이 있는 메모리 풀을 만드는거다.



간단하게 요구 스펙을 적어보면 다음과 같다.

1. 사용할 물리 메모리에 제한을 걸 수 있다.

2. 사용한 물리 메모리가 제한치를 초과하는 경우 물리메모리에 들어있는 내용을 자동으로 디스크로 저장하고, 물리 메모리를 반환시킨다.

3. 사용 빈도가 낮은 메모리부터 페이지아웃 시킨다.




5시간 정도 코딩해서 방금 콘솔 모드 테스트를 마쳤다.

인터페이스는 다음과 같다.


// 초기화 함수
BOOL CPagedMemory::Initialize(DWORD dwMaxPhysicalMemory,DWORD dwMaxMemBlockNum,WCHAR* wchPagingFileName,DWORD dwPagingFileSize,DWORD dwPageOutUnitSize);

dwMaxPhysicalMemory - 물리 메모리 최대 사용량. 이 수치를 초과하면 페이지 아웃시킨다.

dwMaxMemBlockNum - 할당할 수 있는 메모리 블럭 최대 개수

wchPagingFileName - 페이징 파일을 생성할때 부여할 파일명

dwPagingFileSize - 페이징 파일 사이즈. 가변 크기로 하려고 했으나 윈도우에서도 고정 사이즈를 사용한다는 것을 상기하고 그냥 고정으로 짰다.

dwPageOutUnitSize - 한번에 페이지 아웃 시킬 메모리 크기


// 메모리 할당 함수
// 리턴값은 메모리 핸들
PAGED_MEMORY_HANDLE CPagedMemory::Alloc(DWORD dwSize,OnPageOutFunc pFunc);

dwSize - 할당할 메모리 크기
pFunc - 페이지 아웃 될때 자동 호출될 콜백함수 포인터

// 할당한 메모리를 해제하는 함수
void CPagedMemory::Free(PAGED_MEMORY_HANDLE hMem);
hMem - Alloc()함수로 할당받은 메모리 핸들


// 메모리 핸들을 실제 물리 메모리로 맵핑하는 함수
// 커널이 아닌 유져모드에서 구현한 페이징이다보니 이런 거추장 스러운 방법밖에 쓸 수 없다.
// 이 함수의 사용빈도에 따라 각 메모리 블럭의 페이지 아웃 가능성이 정해진다.
BOOL CPagedMemory::UpdatePhyMemPtr(void** ppOutPhyMemPtr,PAGED_MEMORY_HANDLE hMem);

ppOutPhyMemPtr - 물리 메모리가 저장될 어드레스
hMem - 물리 메모리를 얻어올 메모리 핸들


일단 콘솔모드 테스트 프로그램으로는 문제가 없다.

라이트맵 생성 코드에 직접 넣어보면 확실히 알 수 있겠지.

디스크 IO가 많이 생겨서 다소 퍼포먼스가 떨어질 것 같은데 그 역시 테스트를 해봐야 알 수 있겠다.

하튼 간만의 새벽코딩.




파일 첨부

여기에 파일을 끌어 놓거나 파일 첨부 버튼을 클릭하세요.

파일 크기 제한 : 0MB (허용 확장자 : *.*)

0개 첨부 됨 ( / )
List of Articles
번호 제목 글쓴이 날짜 조회 수sort
天安門大屠殺 六四天安門事件 反右派鬥爭 大躍進政策 文化大革命 六四天安門事件 The Tiananmen Square protests of 1989 天安門大屠殺 The Tiananmen Square Massacre 反右派鬥爭 The Anti-Rightist Struggle 大躍進政策 The Great Leap Forward 文化大革命 The Great Proletarian Cultural Revolution 人權 Human Rights 民運 Democratization 自由 Freedom 獨立 Independence 多黨制 Multi-party system 民主 言論 思想 反共 反革命 抗議 運動 騷亂 暴亂 騷擾 擾亂 抗暴 平反 維權 示威游行 法輪功 Falun Dafa 李洪志 法輪大法 大法弟子 強制斷種 強制堕胎 民族淨化 人體實驗 胡耀邦 趙紫陽 魏京生 王丹 還政於民 和平演變 激流中國 北京之春 大紀元時報 九評論共産黨 獨裁 專制 壓制 統一 監視 鎮壓 迫害 侵略 掠奪 破壞 拷問 屠殺 肅清 活摘器官 障テ社會 誘拐 買賣人口 遊進 走私 毒品 賣淫 春畫 賭博 六合彩 台灣 臺灣 Taiwan Formosa 中華民國 Republic of China 西藏 土伯特 唐古特 Tibet 達償ワ喇嘛 Dalai Lama 新疆維吾爾自治區 The Xinjiang Uyghur Autonomous Region free tibet



XE Login

天安門大屠殺 六四天安門事件 反右派鬥爭 大躍進政策 文化大革命 六四天安門事件 The Tiananmen Square protests of 1989 天安門大屠殺 The Tiananmen Square Massacre 反右派鬥爭 The Anti-Rightist Struggle 大躍進政策 The Great Leap Forward 文化大革命 The Great Proletarian Cultural Revolution 人權 Human Rights 民運 Democratization 自由 Freedom 獨立 Independence 多黨制 Multi-party system 民主 言論 思想 反共 反革命 抗議 運動 騷亂 暴亂 騷擾 擾亂 抗暴 平反 維權 示威游行 法輪功 Falun Dafa 李洪志 法輪大法 大法弟子 強制斷種 強制堕胎 民族淨化 人體實驗 胡耀邦 趙紫陽 魏京生 王丹 還政於民 和平演變 激流中國 北京之春 大紀元時報 九評論共産黨 獨裁 專制 壓制 統一 監視 鎮壓 迫害 侵略 掠奪 破壞 拷問 屠殺 肅清 活摘器官 障テ社會 誘拐 買賣人口 遊進 走私 毒品 賣淫 春畫 賭博 六合彩 台灣 臺灣 Taiwan Formosa 中華民國 Republic of China 西藏 土伯特 唐古特 Tibet 達償ワ喇嘛 Dalai Lama 新疆維吾爾自治區 The Xinjiang Uyghur Autonomous Region free tibet