创建多个顶点和索引缓冲区时会消耗大量内存
我遇到了一个非常奇怪的问题。当我在D3D中创建一些非常简单的VertexBuffer和IndexBuffer时,TaskManager报告的内存消耗是巨大的。
我通过 D3D CreateIndexBuffer 方法创建了 60000 个索引缓冲区。每个索引缓冲区包含 6 个索引(int),代表两个三角形。因此,一个索引缓冲区将占用 24 个字节。总内存消耗为 24*60000 = 1,440,000。但任务管理器显示应用程序内存增加了300MB!
我不知道D3D9内部是如何进行内存分配的,但是这个问题在D3D10中也发生了。这是由于内存碎片吗?
这是x86|bebug版本下的,d3d是release版本,windows 7。
I met a very weird issue. When I create some very simple VertexBuffer and IndexBuffer in D3D, the memory consumption reported from TaskManager is huge.
I created 60000 index buffer via D3D CreateIndexBuffer method. Each index buffer contains 6 index (int) which represents two triangles. So, one index buffer will occupy 24 bytes. And total memory consumption would be 24*60000 = 1,440,000. But task manager shows application 300MB memory increase!
I don't know how did D3D9 do the memory allocation internally, but this issues happens also in D3D10. Is this due to memory fragmentation?
This is under x86|bebug version, and d3d is release version, windows 7.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
60000 个索引缓冲区?为什么不直接创建 1 个大索引缓冲区呢?切换所有这些索引缓冲区本身会非常慢。
原因是:您创建的每个索引缓冲区都会产生相关的开销(各种跟踪信息和驱动程序将用来优化它的信息),对于我来说,5K 内存对于该开销来说似乎相当合理。 5K * 60000 大约是 300 兆...
60000 index buffers? Why not just create 1 big index buffer? Switching all those index buffers will be slow as hell in itself.
On to the reason: There will be an overhead associated with every index buffer you create (Various bit of tracking information and bits of info the driver will use to optimise it) and 5K of memory seems quite reasonable to me for that overhead. 5K * 60000 is roughly 300 megs ...
您必须考虑到,仅仅存储 60000 组 6 个整数,还有更多的事情要做。如果您要维护指向所有这些的指针(您应该这样做),则每个指针还需要 4 个字节。这甚至没有考虑到每个顶点缓冲区中存在多个数据成员来跟踪诸如缓冲区类型、元素数量、每个元素的大小/类型、缓冲区是否是动态的、只读的、可写的这样的事实。仅等。
您在另一条评论中提到它是只读和托管的。受管理意味着 Direct3D 存储有关每个缓冲区的大量附加数据,以便在必要时(例如设备重置)可以销毁、重建和重新填充缓冲区。
如前所述,另一个问题是您有 60000 个索引缓冲区,每个索引缓冲区存储 6 个索引来存储 2 个三角形。您可以在三角形扇形或三角形条带中使用 4 个索引。除此之外,我不太确定为什么你需要 600000 套。事实上,您可以拥有一个索引缓冲区并对其进行索引,尽管这听起来很令人困惑。您可以指示 Direct3D 使用从第 6 * n 索引开始的 6 个索引来绘制第 n 对三角形。
不过我离题了,因为这不是你问题的重点。
You have to consider that there's much more going on that just storing 60000 sets of 6 ints. If you're maintaining pointers to all of these, as you should, that's another 4 bytes for each pointer. This isn't even considering the fact that there are several data members present in each vertex buffer keeping track of things like buffer type, number of elements, size/type of each element, whether the buffer is dynamic, read-only, write-only, etc..
You mentioned in another comment that it is read only and managed. Being managed means Direct3D is storing plenty of additional data about each buffer so that it can be destroyed, reconstructed, and refilled when necessary such as the device resetting.
As previously mentioned, the other concern is that you have 60000 index buffers each storing 6 indices to store 2 triangles. You could use 4 indices in a triangle fan or triangle strip. Besides that, I'm not entirely certain why you need 600000 sets of them. You can, in fact, have a single index buffer and index into it, as confusing as that may sound. You can instruct Direct3D to use, say, 6 indices starting at the
6 * n
th index to draw then
th pair of triangles.I digress though, as that is not the focus of your question.