这是
this question的后续工作.我正在编写一个简单的游戏,并且正在寻找最快的方式(重复)在Win32窗口中显示一组RGB数据,而不会出现闪烁或其他工件.
在上一个问题的答案中建议采取了几种不同的方法,但是对于哪个方法是最快的并没有达成共识.所以,我把一个测试程序.代码只是在屏幕上重复地显示帧缓冲区,尽可能快.
这些是我获得的结果,32位数据以32位视频模式运行 – 他们可能会让一些人感到惊讶:
- Direct3D (1): 500 fps - Direct3D (2): 650 fps - DirectDraw (3): 1100 fps - DirectDraw (4): 800 fps - GDI (SetDIBitsToDevice): 2000 fps
鉴于这些数字:
>为什么许多人坚持认为GDI对于这个操作来说太慢了?
>有没有理由喜欢DirectDraw或Direct3D超过SetDIBitsToDevice?
以下简要介绍每个Direct * codepath进行的调用.如果有人知道使用DirectDraw / Direct3D的更有效的方式,请评论.
1. CreateTexture(D3DUSAGE_DYNAMIC,D3DPOOL_DEFAULT); LockRect(); memcpy(); UnlockRect(); DrawPrimitive() 2. CreateTexture(0,D3DPOOL_SYSTEMMEM); CreateTexture(0,D3DPOOL_DEFAULT); LockRect(); memcpy(); UnlockRect(); UpdateTexture(); DrawPrimitive() 3. CreateSurface(); SetSurfaceDesc(lpSurface = &frameBuffer[0]); memcpy(); primarySurface->Blt(); 4. CreateSurface(); Lock(); memcpy(); Unlock(); primarySurface->Blt();
解决方法
这里有几件事要记住.首先,很多“常识”是基于一些不再适用的事实.
在AGP的时代,当cpu直接与GPU通话时,它总是使用基本的PCI协议,以“1x”速率(始终是不可避免的)发生. AGX 2x / 4x / 8x仅在GPU直接连接到内存控制器时应用.换句话说,根据你看的时间,GPU可以从内存中加载纹理的速度高达8倍,就像cpu将相同的数据直接发送到GPU一样.当然,cpu还支持比PCI总线更多的内存带宽.
然而,当事情切换到PCI-E时,这完全改变了.虽然根据路径的带宽可能会有差异,但是没有一般的规则是,内存 – > GPU将比cpu-> GPU快. (大多数)安全的一个概括是,如果你有一个专用的显卡,那么GPU对于显卡上的内存几乎总是比主板上的主内存有更多的带宽.
在你的情况下,这并不重要 – 你正在谈论将数据从cpu空间移动到GPU空间,无论如何.当您将所有(或大部分)计算保留在GPU上时,使用DirectX(或OpenGL)的主要速度差异都会发生,并避免使用cpu(或主内存).它们不(现在AGP是历史)可以显着提高存储器显示带宽.