글 수 83
기본적으로 new,delete와 같다고 생각하시면 됩니다. new, malloc처럼 가변적인 사이즈로 메모리를 할당할 수 있습니다. 리얼타임에서 사용하려고 만든거니까 속도는 물론 얘네들보단 한참 빠릅니다만.
차이점이라면 실제로는 어드레스만 할당해주고 물리 메모리를 사용하지 않는다는 점입니다.
실제로 D3D를 다루다보면 버텍스 버퍼따위를 힙처럼 써야할 때가 있는데요.요샌 드라이버가 꽤 안정되었지만 1년전만 해도 버텍스 버퍼를 수천개씩 만들어대면 E_OUTOFMEMORY를 뱉거나 블루스크린이 뜨곤 했습니다.
이럴때 쉽게 생각할 수 있는 해결책은 버텍스 버퍼를 크게 한덩어리 잡아놓고 맥시멈 사이즈 단위로 잘라 쓰는 방법이죠.
그런데 필요로 하는 가장 작은 블럭은 4바이트 가장 큰 블럭은 102400바이트. 이런식이라면 낭비가 굉장히 심할겁니다. 이런때 버텍스 버퍼를 new나 malloc처럼 쓸 수 없을까 생각하게 되죠.
그 외에도 일전에 게시판에 올렸던 버텍스 버퍼 캐쉬의 경우가 그렇습니다.캐쉬 사이즈는 제한되어있는데 그 안에서 가능한 많은 개체들을 수용하려면 버텍스 버퍼를 최대한 알뜰하게 사용해야합니다. 고정 사이즈 블럭을 남발할 수 없죠.
그럼 어떻게 할까요.
일단 힙 메모리 라이브러리를 만듭니다. 이 녀석은 위에서 적은대로 주소만 뱉어주고 실제로 물리 메모리를 소모하지 않습니다.베이스 어드레스는 바깥에서 지정할 수 있습니다. 편하게 0을 지정하면 0에 대한 인덱스가 리턴되겠죠.
힙 메모리 라이브러리 상위 계층에 버텍스 버퍼 힙이 있습니다.할당받은 어드레스는 실제 버텍스 버퍼 한덩어리에서의 인덱스가 됩니다
.
힙라이브러리에서 메모리 블럭의 가장 적합한 사이즈를 찾아서 할당해주고 해제는 물론 병합까지 해주니까 상위의 버텍스 버퍼힙에선 따로 할게 없습니다.
그냥 리턴되는 어드레스를 가지고 버텍스 버퍼의 스타트 인덱스를 구해서 넘겨주면 되거든요. 즉 버텍스버퍼 리소스 자체는 VB힙에서 가지고 있지만 이 녀석을 쪼개서 할당하고 병합하고 어쩌고 하는 것은 하위의 힙 라이브러리에 전적으로 맡긴다는 것입니다. 리턴되는 어드레스가 인덱스(버텍스 버퍼의 스타트인덱스)역할을 해주니까 한 개의 버텍스 버퍼만으로도 여러개의 버텍스 버퍼처럼 쓸 수 있죠. 물론 고정 블럭을 써도 되지만 메모리 낭비가 심한거죠.
단 버텍스버퍼의 특성상 버텍스 사이즈에 맞게 정렬된 어드레스가 필요하므로 힙라이브러리는 특정 사이즈에 정렬된 어드레스를 리턴할 수 있어야합니다.약간의 짜투리를 낭비시키더라도 말이죠.
최초로 만들어둔 버텍스 버퍼 1개로 모자라는 경우 추가할당하고 필요없으면 다시 릴리즈 하는것 또한 쉽습니다.
힙라이브러리의 어드레스 영역을 꽤 크게 잡아놓고 실제 버텍스 버퍼는 그 1/5이나 1/8정도 사이즈로만 할당해두는거죠.
리턴된 어드레스가 버텍스 버퍼 1개의 사이즈를 넘어가는 영역이면 버텍스 버퍼를 한개 더 만들고 그 버텍스 버퍼에 대한 인덱스로 변환해서 할당 요청을 처리하면 됩니다.할당할때마다 관련된 실제 버텍스 버퍼의 레퍼런스 카운트를 올리고 해제할때마다 카운트를 내리니까 추가할당한 버텍스 버퍼가 더 필요없다면 자동적으로 해제됩니다.
설명이 장황한데 이해가 되셨는지...
차이점이라면 실제로는 어드레스만 할당해주고 물리 메모리를 사용하지 않는다는 점입니다.
실제로 D3D를 다루다보면 버텍스 버퍼따위를 힙처럼 써야할 때가 있는데요.요샌 드라이버가 꽤 안정되었지만 1년전만 해도 버텍스 버퍼를 수천개씩 만들어대면 E_OUTOFMEMORY를 뱉거나 블루스크린이 뜨곤 했습니다.
이럴때 쉽게 생각할 수 있는 해결책은 버텍스 버퍼를 크게 한덩어리 잡아놓고 맥시멈 사이즈 단위로 잘라 쓰는 방법이죠.
그런데 필요로 하는 가장 작은 블럭은 4바이트 가장 큰 블럭은 102400바이트. 이런식이라면 낭비가 굉장히 심할겁니다. 이런때 버텍스 버퍼를 new나 malloc처럼 쓸 수 없을까 생각하게 되죠.
그 외에도 일전에 게시판에 올렸던 버텍스 버퍼 캐쉬의 경우가 그렇습니다.캐쉬 사이즈는 제한되어있는데 그 안에서 가능한 많은 개체들을 수용하려면 버텍스 버퍼를 최대한 알뜰하게 사용해야합니다. 고정 사이즈 블럭을 남발할 수 없죠.
그럼 어떻게 할까요.
일단 힙 메모리 라이브러리를 만듭니다. 이 녀석은 위에서 적은대로 주소만 뱉어주고 실제로 물리 메모리를 소모하지 않습니다.베이스 어드레스는 바깥에서 지정할 수 있습니다. 편하게 0을 지정하면 0에 대한 인덱스가 리턴되겠죠.
힙 메모리 라이브러리 상위 계층에 버텍스 버퍼 힙이 있습니다.할당받은 어드레스는 실제 버텍스 버퍼 한덩어리에서의 인덱스가 됩니다
.
힙라이브러리에서 메모리 블럭의 가장 적합한 사이즈를 찾아서 할당해주고 해제는 물론 병합까지 해주니까 상위의 버텍스 버퍼힙에선 따로 할게 없습니다.
그냥 리턴되는 어드레스를 가지고 버텍스 버퍼의 스타트 인덱스를 구해서 넘겨주면 되거든요. 즉 버텍스버퍼 리소스 자체는 VB힙에서 가지고 있지만 이 녀석을 쪼개서 할당하고 병합하고 어쩌고 하는 것은 하위의 힙 라이브러리에 전적으로 맡긴다는 것입니다. 리턴되는 어드레스가 인덱스(버텍스 버퍼의 스타트인덱스)역할을 해주니까 한 개의 버텍스 버퍼만으로도 여러개의 버텍스 버퍼처럼 쓸 수 있죠. 물론 고정 블럭을 써도 되지만 메모리 낭비가 심한거죠.
단 버텍스버퍼의 특성상 버텍스 사이즈에 맞게 정렬된 어드레스가 필요하므로 힙라이브러리는 특정 사이즈에 정렬된 어드레스를 리턴할 수 있어야합니다.약간의 짜투리를 낭비시키더라도 말이죠.
최초로 만들어둔 버텍스 버퍼 1개로 모자라는 경우 추가할당하고 필요없으면 다시 릴리즈 하는것 또한 쉽습니다.
힙라이브러리의 어드레스 영역을 꽤 크게 잡아놓고 실제 버텍스 버퍼는 그 1/5이나 1/8정도 사이즈로만 할당해두는거죠.
리턴된 어드레스가 버텍스 버퍼 1개의 사이즈를 넘어가는 영역이면 버텍스 버퍼를 한개 더 만들고 그 버텍스 버퍼에 대한 인덱스로 변환해서 할당 요청을 처리하면 됩니다.할당할때마다 관련된 실제 버텍스 버퍼의 레퍼런스 카운트를 올리고 해제할때마다 카운트를 내리니까 추가할당한 버텍스 버퍼가 더 필요없다면 자동적으로 해제됩니다.
설명이 장황한데 이해가 되셨는지...
"가장 적합한 사이즈를 찾아서 할당해주고 해제는 물론 병합까지 해주니까" <-- 정말 대단합니다 ^^
저도 한번 만들어봐야겠네요 ㅎㅎ 답변감사합니다.