Game Dev/Scrap

Resource Management Best Practices

AKer 2008. 7. 23. 16:05
반응형

원문 :
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/Resource_Management_Best_Practices.asp

출처 :
http://blog.naver.com/jacking75/140030532889

번역 :
이만희 (manilee@chol.com, manilee@sonokong.co.kr)



Resource Management Best Practices

By Chuck Walbourn, Software Design Engineer
Microsoft Game Technology Group
June 2005

Introduction
Managed textures (also known as "automatic texture management") have been available in DirectX since version 6, with several revisions and enhancements made in subsequent releases. As of the Direct3D 9 API, the automatic resource management includes support for textures, vertex buffers, and index buffers all with a consistent shared interface. By using the Direct3D resource manager, applications can greatly simplify the handling of lost-device situations and can rely on the system to handle a reasonable amount of over-commitment of video memory resources.

Managed texture("자동 texture 관리"라고 알려진)는 DirectX 버젼 6이후로 사용 가능했으며, 여러 번의 리비젼과 개선을 거쳤다. Direct3D 9 API에 이르러서 자동 리소스 관리(Automatic resource management)는 texture, 공유된 interface(consistent shared interface)로 구성된 vertex buffer, index buffer 지원을 포함하고 있다. Direct3D의 리소스 관리자를 사용함으로써, 응용프로그램은 lost-device 상황을 매우 간단히 다룰 수 있고,  비디오 메모리 리소스의 over-commitment의 적당한 양을 다루는 것을 시스템에 의존할 수 있다.

Developers sometimes have difficulties using managed resources, in part due to the abstract nature of the system. While many common scenarios for resources are a good fit for managed resources, some cases are more performant using unmanaged resources. This article will discuss best practices for dealing with resources generally, how managed and unmanaged resources behave, and provide some detail on how resources are typically handled by the runtime and drivers.

개발자는 때때로 시스템의 숨겨진 특징 때문에 managed 리소스를 사용하는데 어려움을 가진다.  일반적인 많은 경우가 managed 리소스를 사용하는 것이 더 좋을 테지만, 어떤 경우는 unmanaged 리소스를 사용하는 것이 더 성능에 좋을 수 있다. 이글은 일반적으로 어떻게 managed와 unmanaged 리소스가 행동하는지에 대한 최고 Practice를 제공하고  실행시간에 드라이버에 의해 리소스가 어떻게 다루어지는 지에 대한 자세한 내용을 제공할 것이다.

Contents:
- Video Memory
- Managed Resources
- Driver Managed Resources
- Default Resources
- System Memory Resources
- General Recommendations



Video Memory
In order for the video system to make use of a resource, it must be located in memory accessible to the GPU. Local video memory is the most performant for the GPU, and certain resources (such as render targets and depth/stencil buffers) must be located in local video memory. With the advent of AGP, the GPU can also access a portion of the system memory directly. This memory area, known as the AGP aperture, is referred to as 'non-local video memory' and is not available for other purposes. Non-local video memory can be read from and written to by the CPU, which typically has no high-performance access to local video memory, and is thus ideal for use as a shared memory resource. A key thing to remember about AGP memory is that it, like local video memory, is invalidated in lost-device situations and persistent assets located there must be restored.

비디오 시스템이 리소스를 사용하기 위해서, 그 리소스는 GPU가 접근 가능한 데 위치해야만 한다. Local video memory는 GPU가 가장 빨리 접근할 수 있고, 어떤 리소스(Render target, depth/stencil buffer)는 local video memory에 위치해야 하는 것도 있다. AGP의 출현과 함께 GPU는 시스템 메모리의 일부를 직접 접근할 수 있게 되었다. 이 메모리 영역은 AGP aperture라고 알려져 있으며 'non-local video memory'로 참조되어 진다. 이것은 다른 용도로 사용되어 질 수 없다.  Non-local video memory는 local video memory에 빠른 속도로 접근할 수 없는 CPU에 의해 읽혀지고, 쓰여질 수 있으며 공유 메모리 리소스로써 이상적으로 사용되어 질 수 있다. AGP 메모리에 대해 기억해 두어야할 중요한 것은 local video memory와 같이 lost-device 상황에서는 무효화되어진다는 것과 유지되어져야 할 자원 있는 위치에 되돌려져야 한다는 것이다.

Some integrated video solutions make use of a Unified Memory Architecture where main memory is addressable by all components of the systems. Direct3D supports UMA without requiring any change to the application, utilizing the same hints as for local video memory configurations. For such systems, resources are always located in system memory and the driver is responsible for ensuring resources work much like they do in a more traditional architecture while taking advantage of UMA's properties and any specific behavior of the hardware implementation.

일부 Unifed Memory Architecture를 사용하는 통합 비디오 솔루션은 메인 메모리가 시스템의 모든 부분에 의해 접근할 수 있다. Direct3D는 응용프로그램의 어떤 변화없이, local video memory 구성에 대한 그런 정보없이 UMA를 사용할 수 있다. 그러한 시스템에서 리소스는 항상 시스템 메모리에 위치하고 있고, 드라이버는 리소스가 UMA의 특성과 하드웨어 구현 방식의 잇점을 활용하는 동안 기존의 전통적인 Architecture(통합되어 있지 않은 구조)와 상당히 유사하게 동작하도록 보장해주는 책임을 가지고 있다.

Managed Resources
The majority of your resources should be created as managed resources in POOL_MANAGED. All your resources will be created in system memory, and then copied as needed into video memory. Lost-device situations will be handled automatically from the system memory copy. Since not all managed resources are required to fit into video memory all at once, you can over commit memory where a smaller video memory working set of resources is all that is required to render in any given frame. Note that it is likely that the majority of this backing-store system memory will be paged out to disk over time, which is why the Reset operation can be slow due to the need to page this data in to restore the lost video memory.

당신의 리소스 대부분을 managed 리소스인 POOL_MANAGED로 생성해야 한다. 당신의 모든 리소스들은 시스템 메모리에서 생성되고 필요한 순간에 비디오 메모리로 복사되어 질 것이다. Lost-device 상황에서는 자동으로 시스템 메모리로부터 복사함으로써 처리될 것이다. 모든 managed 리소스가 한번에 비디오 메모리에 넣는 것이 요구되어지지 않기 때문에, 당신은 주어진 어떤 프레임을 render하기 위해 요구되어지는 모든 리소스를 사용하기에는 다소 작은 메모리에 과도하게 보낼 수도 있다.  대부분의 backing-store 시스템 메모리는 오랫 동안 디스크로 복사되어지기(page out, 가상메모리로 이동) 쉬울 것이다.  이것이 재설정 명령(Reset operation)이 느린 이유는 잃어버린 비디오 메모리를 다시 담는데 이러한 data를 가상메모리에 담을(page할) 필요성 때문이다.

The runtime keeps a timestamp for the last time a resource is used, and when a video memory allocation fails for loading a needed managed resource, it will release resources based on this timestamp in a LRU fashion. Usage of the SetPriority API takes precedence over the timestamp, so more commonly used resources should be set to a higher priority value. Direct3D 9.0 has limited information about the video memory managed by the driver, so the runtime may have to evict several resources in order create a large enough region for the allocation to succeed. Proper priorities can help eliminate situations where something gets evicted and then is required again shortly there-after. The application can also use the EvictManagedResources API call to force all the managed resources to be removed. Again, this can be a time-consuming operation to reload all the resources required for the next frame, but is very useful for level transitions where the working set changes significantly and removing video memory fragmentation.

리소스가 사용된 가장 마지막 시간은 timestamp로 runtime이 가지고 있다가 필요한 managed 리소스를 불러오는 동안 비디오 메모리 할당이(Local video memory) 실패가 발생 때,  timestamp를 근거로 하여 가장 최근에 사용된 리소스를 나중에(LRU(Least Recently Used) fashion) 해체할 것이다. SetPriority API를 사용한 것은 timestamp보다 우선한다. 그래서 상당히 자주 사용되어지는 리소스는 더 큰 우선 순위값을 설정해야 한다. Direct3D 9.0은 드라이버에 의해 관리되어지는 비디오 메모리에 대한 정보가 제한적이다. 그래서 runtime은 다음 할당할 충분한 영역을 확보하기 위해 연속된 몇개의 리소스를 제거해야 할 지도 모른다. 적절한 우선순위값은 어떤 것이 제거되고 난 직후 다시 필요한 상황을 없애는 데, 도움을 줄 수 있다. 응용 프로그램은 EvictManagedResources API를 호출하여 모든 managed 리소스를 강제로 제거할 수도 있다. 이것은 다음 프레임에 필요한 리소스를 모두 다시 읽어들여야 하기 때문에 시간을 허비하는 명령이 될 수도 있다. 그러나 작업 데이터(working set)의 변화가 큰, 레벨 전환과 비디오 메모리의 단편화를 제거하는 데는 유용할 수 있다.

A frame count is also kept to allow the runtime to detect if the resource it just choose to evict was used early the current frame, which implies a 'thrashing' situation where more resources are in use in a single frame than will fit into video memory. This triggers the replacement policy to switch to a MRU fashion rather than LRU for the remainder of the frame as this tends to perform slightly better under such conditions. Such 'thrashing' behavior will significantly impact the rendering performance. Note that the notion of current frame is tied to EndScene, so any application making use of managed resources needs to make regular calls to this method.

제거할려고 선택한 리소스가 현재 프레임의 초기에 사용된 것인지를 runtime이 알아내기 위해 Frame count를 가지고 있다.  이것은 비디오 메모리에 넣을 수 있는 양보다 더 많은 리소스가 한 프레임내에서 사용되어지는 "thrashing" 상황(실제 메모리보다 사용하는 data가 더 많아서, paging이 과도하게 일어나는 상황)을 의미한다. 이것은 그러한 상황에서 좀 더 성능이 향상되는 경향이 있기 때문에 프레임의 남은 시간동안 LRU(Least Recently Used)보다는 MRU(Most Recently Used) fashion으로 전환하는 메모리 교체 정책을 바꾸도록 한다. 그러한 "thrashing" 상황은 rendering 성능에 상당한 영향을 준다. 여기서의 현재 프레임의 개념은 EndScene을 기준으로 한다. 그래서 managed 리소스를 사용하는 모든 응용프로그램은 일정하게 이 method를 호출할 필요가 있다. (BeginScene 호출 이후, EndScene 호출될 때, 이때 사용하는 managed 리소스의 양이 비디오 메모리 보다 많으면, thrashing 상황이 발생한다.)

Developers looking to find more information about how managed resources are behaving in their application can make use of the RESOURCEMANAGER event query via the IDirect3DQuery9 interface. This only works when using the debug runtimes so this information cannot be depended upon by the application, but it provides deep detail on the resources managed by the runtime.

개발자는 그들의 응용프로그램에서 managed 리소스가 어떻게 행동하는지에 대한 더 많은 정보를 찾는 방법은 IDirect3DQuery9 Interface를 통해 RESOURCEMANAGER event query를 사용하는 것이다. 이것은 debug runtime을 사용할 때만 동작한다. 그래서 응용프로그램에 의해 의존되어질 수 없는 정보이지만, runtime에 의해 관리되어지는 리소스에 대한 더 많은 정보를 제공할 것이다.

While understanding how the resource manager works can help when tuning and debugging your applications, it is important to not tie your application too tightly to the implementation details of the current runtime or drivers. Revisions of the driver or changes in hardware can significantly change the behavior, and future versions of Direct3D will have significantly improved and sophisticated resource management.

리소스 관리자가 어떻게 동작하는지를 이해하는 것은 당신의 응용프로그램을 디버깅하고 튜닝하는 데, 도움을 줄 수 있는 반면, 당신의 응용프로그램이 드라이버나 현재 runtime의 세세한 구현에 너무 얽매이지 않도록하기 위해서 중요하다. 드라이버의 리버젼이나 하드웨어의 변화에 따라 이러한 동작은 상당히 변할 수도 있다. 그리고 다음 버젼의 Direct3D는 상당히 향상되고, 대중화된 리소스 관리를 가질 것이다.

Driver Managed Resources
Direct3D drivers are free to implement the 'driver managed textures' capability, indicated by D3DCAPS2_CANMANAGERESOURCE, which allows the driver to handle the resource management instead of the runtime. For the (rare) driver that implements this feature, the exact behavior of the driver's resource manager can vary widely and you should contact the driver vendor for details on how this works for their implementation. Alternatively, you can ensure that the runtime manager is always used instead by specifying D3DCREATE_DISABLE_DRIVER_MANAGEMENT when creating the device.

Direct3D 드라이버는 runtime 대신 드라이버가 리소스 관리를 처리할 수 있도록 하는 D3DCAP2_CANMANAGERSOURCE 를 가지고 '드라이버 관리 texture(driver managed textures)'를 구현할 수 있다.  매우 드물지만, 이런한 기능을 구현한 드라이버의 리소스 매니져의 정확한 동작 방식은 매우 다양할 수 있고, 어떻게 구현되었는지에 대한 자세한 내용은 드라이버 벤더에 문의해야 한다. runtime 매니저가 항상 사용되기를 보장받기를 원할 때는 디바이스를 생성할 때, D3DCREATE_DISABLE_DRIVER_MANAGEMENT를  사용하면 된다.

Default Resources
While managed resources are simple, efficient, and easy-to-use there are times when using video memory directly is preferred or even required. Such resources are created in the POOL_DEFAULT category. Making use of such resources does cause additional complications for your application. Code is required to cope with the lost-device situation for all the POOL_DEFAULT resources, and performance considerations must be taken into account when copying data into them. Failure to specify USAGE_WRITEONLY or making a render target lockable can also impose serious performance penalties.

managed 리소스가 간단하고, 효율적이고, 쉽게 사용할 수 있는 반면, 비디오 메모리를 직접 사용해야하는 게 더 낫거나 필요할 때가 있다. 그러한 리소스는 POOL_DEFAULT로 생성되어 진다. 그러한 리소스의 사용은 응용 프로그램이 조금 복잡해지게 된다. lost-device 상황에서 모든 POOL_DEFAULT 리소스에 대해 대응되는 코드를 작성해 주어야 한다. 그리고 그것을 복사할 때도 성능상 여러가지 상황을  고려해 주어야 한다. USAGE_WRITEONLY로 지정하는 것이 실패하거나 lock을 걸수 있는 render target을 만드는 것을 실패하는 것은 성능상의 심각한 부담을 지어준다.

Calling Lock on a POOL_DEFAULT resource is more likely to cause the GPU to stall than working with a POOL_MANAGED resource unless using certain hint flags. Depending on the location of the resource the pointer returned could be to a temporary system memory buffer or it can be a pointer directly into AGP memory. If it is a temporary system memory buffer, data will need to be transferred to the video memory after the Unlock call. If the video resource is not write-only, data will have to be transferred into the temporary buffer during the Lock. If it is an AGP memory area, temporary copies are avoided but the cache behavior required can result in slow performance.

만약 어떤 hint flag를 사용하지 않고, Lock을 POOL_DEFAULT 리소스에 호출하는 것은 GPU가 POOL_MANAGED 리소스를 가지고 동작할 때보다 stall(아무 동작도 하지 못하는 상태)에 빠지기 쉽다. 리소스의 위치에 의존해서 받은 포인터는 임시 시스템 메모리 버퍼(temporary system memorly buffer)이거나 AGP 메모리 바로 지칭하는 포인터일 수 있다. 만약 임시 시스템 메모리 버퍼라면, data는 Unlock이 호출된 뒤 비디오 메모리로 전송되어져야 한다. 만약 AGP 메모리 영역이라면, 임시 복사는 피할 수 있으나, 요구되는 캐쉬 동작은 성능에 나쁜 영향을 끼칠 수 있다.

Care should be taken to write a full cache line of data into any pointer to AGP aperture memory to avoid the penalty of write-combing which induces a read/write cycle, and sequential access of the memory area is preferred. If your application needs to make random access to data during creation and you do not wish to make use of a managed resource for the buffer, you should work with a system memory copy instead. Once the data has been created, you can then stream the result into the locked resource memory to avoid paying a high penalty for the cache write-combing operation.

read/write cycle을 하게 만드는 write-combing penalty를 피하기 위해 AGP aperture 메모리를 가리키는 어떤 포인터로 full cache line의 data를 쓰는데 주의를 기울여야 한다. 그리고, 메모리 영역의 순차적인 접근이 선호되어진다.  만약 당신의 응용프로그램이 생성되는 동안 data로의 임의 접근을 할 필요가 있고, buffer에 managed 리소스를 사용하기를 원하지 않는다면, 대신해서 system 메모리 복사를 통해 작업해야 한다. 일단 data가 생성되면, cache write-combing operation을 하기 위한 높은 penalty 지불하는 것을 피하기 위해서 당신은 그 결과를 locked 리소스 메모리에 보낼 수 있다.

The LOCK_NOOVERWRITE flag can be used to append data in an efficient manner for some resources, but ideally multiple Lock and Unlock calls to the same resource can be avoided. Making proper use of the various Lock flags is important to optimal performance, as is using a cache-friendly data access pattern when filling locked memory.

LOCK_NOOVERWRITE flag는 어떤 리소스에는 효과적인 방법으로 data를 추가하는데, 사용되어질 수 있으나, 이론적으로 같은 리소스를 두번 Lock, Unlock 호출하는 것을 피할 수 있다. 다양한 Lock flag를 적절히 사용하는 것은 lock을 건 메모리를 채울 때, 캐쉬에 유리한 data 접근 방법을 선택할 수 있으므로 성능최적화에 중요하다.

Using Both Managed and Default Resources
Mixing allocations of managed and POOL_DEFAULT resources can cause video memory fragmentation and confuse the runtime's view of the video memory available for managed resources. Ideally, you should create all POOL_DEFAULT resources before making use of POOL_MANAGED resources or make use of the EvictManagedResources call before allocating unmanaged resources. Remember that all allocations made from POOL_DEFAULT that reside in video memory tie up memory for the life that resource that is unavailable for use by the resource manager or for any other purpose.

managed와 POOL_DEFAULT 리소스를 혼합해서 사용하는 것은 비디오 메모리 단편화와 runtime에 입장에서 managed 리소스를 위한 메모리 확보를 혼란스럽게 할 수 있다.  이론적으로는 POOL_MANAGED 리소를 호출하기전에 모든 POOL_DEFAULT 리소스를 생성하거나, unmanaged 리소스를 할당하기 전에  EvictManagerdResource 호출을 사용해야 한다.  비디오 메모리에 있는 POOL_DEFAULT로 만든 모든 할당은 일생동안 메모리를 리소스 관리자나 다른 목적에 의해 사용되어 질 수 없도록 묶어 버린다는 사실을 기억해라.

Note that unlike previous versions of Direct3D, the version 9 runtime will automatically evict some managed resources before giving up on a failed unmanaged resource allocation for a lack of video memory, but this can potentially create additional fragmentation and even force a resource into a sub-optimal location (a static texture in non local video memory for example). Again, it is best to allocate all required unmanaged resources up-front and before using any managed ones.

이전의 다른 Direct3D 버전과는 달리 9버전 runtime은 비디오 메모리가 부족으로 unmanaged 리소스로 할당이 실패하기 전에 자동으로 managed 리소스를 폐기할 것이다. 그러나 이것은 잠재적으로 추가적인 단편화를 생성시키고, 리소스가 덜 최적화된 위치에 할당되도록 할 것이다. (예를 들면, static texture를 Local video memory에 두지 못하는 것) 다시 말해, 필요한 모든 unmanaged 리소스는 managed 리소스를 사용하기전에  먼저 할당하는 것이 최선의 방법이다.

Dynamic Default Resources
Data that is generated and updated at a high frequency has no need for the backing-store since all the information will be re-created when restoring the device. Such data is typically best created in POOL_DEFAULT specifying the USAGE_DYNAMIC hint so the driver can make optimization decisions when placing the resource knowing it will be updated often. This typically means putting the resource into non-local video memory, and thus is usually much slower for the GPU to access than local video memory. For UMA architectures, the driver might choose a particular placement for dynamic resources to optimize for CPU write access.

아주 빈번히 생성되고, 업데이트되는 data는 backing-store에 둘 필요가 없다. 왜냐하면 모든 정보는 디바이스에 저장될 때, 재생성되기 때문이다. 그러한 data는 USAGE_DYNAMIC hint를 지정하고, POOL_DEFAULT에 생성하는 것이 최선이다. 그렇게 함으로 드라이버가 그것이 자주 업데이트되어지는 것을 알고 있는 리소스를 배치할 때 최적의 결정을 할 수 있다. 이것은 리소스를 non-local video memory에 둔다는 것을 의미하고, non-local video memory는 일반적으로 local video memory에 비해 접근 속도가 훨씬 느리다. UMA architecture는 드라이버가 CPU의 쓰기 접근을 최적화하기 위해 dynamic 리소스를 특정한 위치에 둘 수 있다.

This usage is typical for software skinning solutions and CPU-based particle systems filling out vertex/index buffers, and the LOCK_DISCARD flag will ensure that stalls are not created in cases where the resource is still in use from the previous frame. Using a managed resource in this case would update a system memory buffer, which would then be copied to video memory, and then used for only a frame or two before being replaced. For systems with non-local video memory, the extra copy is eliminated by proper use of this dynamic pattern.

이 usage(USAGE_DYNAMIC)는 소프트웨어 skinning 방법과 Vertex/index buffer를 채우는 CPU기반 particle 시스템 에 전형적으로 사용된다. 그리고, LOCK_DISCARD flag가 앞 전 프레임에서 여전히 사용되어진 리소스의 경우에 stall이 생기지 않도록 해 준다. managed 리소스를 이러한 경우에 사용하는 것은 비디오 메모리에 복사되어져야하는 system 메모리 buffer를 한 두 프레임 밖에 사용하지 못하고 업데이트 시킨다.  non-local video memory를 가진 시스템은 이러한 dynamic 유형을 적절히 사용하면 추가적인 복사 과정을 제거할 수 있다.

Standard textures cannot be locked, and can only be updated via UpdateSurface or UpdateTexture. Some systems support dynamic textures, which can be locked and use the LOCK_DISCARD pattern, but a capabilities bit (D3DCAPS2_DYNAMICTEXTURES) must be checked before making use of such resources. For highly dynamic (video or procedural) textures, your application could create matching POOL_DEFAULT and POOL_SYSTEMMEM resources and handle video-memory update via the UpdateTexture API. For high frequency partial updates, the UpdateTexture paradigm is likely the better choice.

표준 texture는 lock되어지고, UpdateSurface나 UpdateTexture를 통해서만 갱신되어 질 수 있다. 어떤 시스템은 LOCK_DISCARD 유형을 사용하고, Lock을 걸 수 있는 dynamic texture를 지원하다. 하지만, 그러한 리소스를 사용하기전에 능력 비트(capabilities bit)(D3DCAP2_DYNAMICTEXTURES)를 확인해 보아야 한다. 자주 바뀌는 texture(video나 순차)는 응용프로그램에서 POOL_DEFAULT와 POOL_SYSTEMMEM 리소스의 짝을 두어 생성할 수 있고, UpdateTexture API를 통해 비디오 메모리 update를 처리해 할 수 있다. 일부만 자주 바뀌는 경우는 UpdateTexture 유형을 더 좋은 선택이다.

As useful as dynamic resources can be, be careful when designing systems that rely heavily on dynamic submission. Static resources should be placed into POOL_MANAGED to ensure both good utilization of local video memory, and to make more efficient use of limited bus and main memory bandwidth. For resources that are 'semi-static', you may find that the cost of an occasional upload to local video memory is much less than the constant bus traffic generated by making them dynamic.

dynamic submission에 크게 의존하는 시스템을 만들 때는 dynamic 리소스가 유용하도록 주의를 기울여라. Static 리소스는 POOL_MANAGED에 두어서 local video memory를 잘 활용할 수 있도록 해야하고, 제한된 bus와 메인 메모리의 bandwidth를 효과적으로 만들어야 한다. semi-static한 리소스는 local video memory로 자주 올리는 부담이 그것을 dynamic으로 함으로 생기는 끊임없는 bus traffic 보다 작다는 것을 알 수 발견할 것이다.

System Memory Resources
Resources can also be created in POOL_SYSTEMMEM. While they cannot be used by the graphics pipeline, they can be used as sources for updating POOL_DEFAULT resources via UpdateSurface and UpdateTexture. Their locking behavior is simple, although stalls might occur if they are in use by one of the previously mentioned methods.

리소스는 POOL_SYSTEMMEM로 생성할 수 있다. 그것은 그래픽 파이프라인을 통해 사용할 수 없는 반면, 그것은 UpdateTexture와 UpdateSurface를 통한 POOL_DEFAULT 리소스를 업데이트함으로 그것을 소스로써 사용할 수 있다. 만약 앞전에 언급된 방법중 하나로 사용되어진다면, stall을 발생할 수 있다하더라도 그것의 locking 방식은 간단하다.

Though they reside in system memory, POOL_SYSTEMMEM resources are limited to the same formats and capabilities (such as maximum size) supported by the device driver. The POOL_SCRATCH resource type is another form of system memory resource that can utilize all formats and capabilities supported by the runtime, but cannot be accessed by the device. Scratch resources are intended primarily for use by content tools.

비록 그들은 시스템 메모리에 있지만, POOL_SYSTEMMEM 리소스는 디바이스 드라이버에 의해 지원되어지는 같은 용량과 형식에 제한 받는다. POOL_SCRATCH 리소스형은 runtime에 의해서 지원되는 모든 형식과 용량을 사용할 수 있는 또 다른 시스템 메모리의 한 유형이지만, 디바이스는 접근할 수 없다. Scratch 리소스는 content 툴에 의해 주로 사용되어지는 경향이 있다.



General Recommendations
Getting the technical implementation details of resource management correct will go a long way to achieving your performance goals in your application. Planning how the resources are presented to Direct3D and the architectural design around getting the data loaded in a timely fashion is a more complicated task. We recommend a number of best practices when making these decisions for your application:

올바른 리소스 관리에 대한 상세한 기술적인 구현을 가지고 당신의 응용프로그램의 성능을 목표치까지 올리는 데는 오랜 시간이 걸릴 것이다.

Pre-process all your resources. Relying on expensive load-time conversion and optimization for your resources is convenient during development, but puts a high performance burden on your users. Pre-processed resources are faster to load, faster to use, and gives you the option of doing sophisticated off-line work.

당신의 모든 리소스에 대해 전처리를 해라. 리소스를 읽어들일 때, 변환하고, 최적화하는 것이 개발 중에는 편리하나, 높은 성능에 대한 부담은 당신에게 지어진다.전처리된 리소스는 읽어들이고, 사용하는 데 더 빠르고, 대중화된 off-line 작업이 선택으로 주어진다.

Avoid creating many resources per frame. The driver interactions required can serialize the CPU and GPU, and the operations involved are heavy-weight as they often require kernel transitions. Spread out creation over several frames or reuse resources without creating/releasing them. Ideally, you should wait several frames before locking or releasing resources recently used to render.

프레임 중에 많은 리소스를 생성하는 것을 피하라.  요구되는 드라이버의 상호작용은 CPU와 GPU를 serialize할 수 있고, 따르는 연산은 자주 Kernel transition이 요구 되어지는 무거운 작업이다. 리소스 생성을 여러 프레임에 걸쳐 나누어서 하거나, 생성, 소멸을 하지 않고 재 사용하라. 이론적으로 당신은 최근에 렌더링되는 데 사용한 리소스를 release하거나 locking하기 전에 여러 프레임을 기다려야 한다.

Be sure to unbind all resource channels (i.e. stream sources, texture stages, and current indices) at the end of the frame. This will ensure that dangling references to resources are removed before they cause the resource manager to keep resources resident that are actually no longer in use.

프레임의 끝에는 모든 리소스 channel(stream sources, texure sources, current indices)을 풀어라. 이것은 그 리소스들이 리소스 manager에 의해 실제로는 더 이상 사용되지도 않는 리소스를 메모리에 유지시키도록 하기전에 애매모호한 reference가 제거되어지도록 해 준다.  (역자 - bind를 풀어라. 다음 프레임의 처음에는 마지막에 설정한 값이 바로 재사용될 가능성이 없다.)

For textures, use compressed formats (e.g. DXTn) with mip-maps and consider making use of a texture atlas. These greatly reduce bandwidth requirements and can reduce the overall size of the resources making them more efficient.

texture는 mip-maps을 가진 압축 형식(DXTn)을 사용하고 texture atlas(여러 texture를 하나에 집어 넣어 사용) 사용을 고려해라. 이것은 필요한 bandwidth를 상당히 줄여주고, 전체 리소스 크기를 줄여서 더 효율적으로 만들어 준다.

For geometry, make use of indexed geometry as this helps compress vertex buffer resources and modern video hardware is heavily optimized around reuse of vertices. By making use of programmable vertex shaders, you can compress the vertex information and expand it during the vertex processing. Again, this helps reduce bandwidth requirements and makes vertex buffer resources more efficient. Be careful about over-optimizing your resource management. Future revisions of drivers, hardware, and the operating system can potentially cause compatibility problems if the application is tuned too heavily to a particularly combination. Since most applications are CPU bound, expensive CPU-based management generally causes more performance issues than they solve.

geometry는 indexed geometry를 사용해라. 왜냐하면, 이것은 vertex buffer 리소스를 압축하는 데, 도움을 추고, 최근 비디오 하드웨어는 vertex의 재사용에 상당히 최적화되어 있다. Programmable Vertex Shader를 사용함으로써, 당신은 vertex 정보를 압축할 수 있고, vertex processing 중에 vertex 정보를 확장할 수 있다.  다시말해 이것은 필요한 bandwidth를 줄이고, vertex buffer 리소스를 좀 더 효율적으로 사용할 수 있도록 도와 준다. 당신의 리소스 관리에 과도한 최적화에 대해 주의해라. 다음 버젼의 드라이버, 하드웨어, 운영체제는 응용 프로그램에서 특정한 조합에 대해 너무 많은 조정을 가하면 잠재적으로 호환성에 문재를 일으킬 수도 있을 것이다. 대부분의 응용프로그램이 CPU Bound(CPU 속도가 가장 많은 부하를 차지한다는 뜻)이기 때문에 너무 과도한 CPU기반 관리는 일반적으로 그 성능 문제를 해결하기 보다는 성능 상 문제를 읽으킨다.

반응형

'Game Dev > Scrap' 카테고리의 다른 글

Starcraft 2 Effects & Techniques  (0) 2008.08.20
The Function Pointer Tutorial  (0) 2008.08.11
Device Lost Handling  (0) 2008.07.23
Synchronized block in C++  (0) 2008.06.09