IDirect3DDevice9::Present is sync or async?

Started by
5 comments, last by moon2012 12 years ago
After the function return, we can see the result on screen or it's not guaranteed.
I found a strange issue when testing multi-monitor performance(try to get the maximal FPS).
For each monitor I create a thread, in the thread function I create a child window, Direct3D device and present continuously. The pseudo code looks like:

while(true)
{
DWORD dwStartTime = timeGetTime();

BeginScene();
......
EndScene();
Present();

DWORD dwEndTime = timeGetTime();
}

dwEndTime - dwStartTime is about 7ms, it seems that the FPS should be 1000 / 7 = 142. but the actual FPS is about 30. I debug and find that the interval after execute the last line code(DWORD dwEndTime = timeGetTime();) and go back to the first line(DWORD dwStartTime = timeGetTime();) is about 25ms, so it slow down the FPS. It seems that the CPU can't get the time slice and can't run this thread's code, but at that time the CPU usage is only about 10%.
The test result is base on the machine utilize 4 display cards and 16 outputs, all threads almost get the same result; when only utilize 2 display cards, the actual FPS can reach to 80 for each moniotor.
I can't understand why this happen? In despite of Present function is sync or async, after execute the last line code, is should execute the first line code very quickly if cpu usage is low.
Advertisement
Present is asynchronous, but can block for two reasons:

1. If you enable vertical sync, Present will block until the VBLANK period
2. If you're not using VSYNC and you're GPU-bound, then Present will start to block after the CPU gets a few frames ahead of the GPU

If you're utilizing multiple devices and outputs, then aren't you calling Present multiple times per "frame"?
I don't use VSYNC.
Since "Present will start to block after the CPU gets a few frames ahead of the GPU", why it's asynchronous? If it's asynchronous, it should return as immediately.
The driver needs to block at some point, otherwise it would need to use an unbounded amount of memory to queue up commands for the GPU. It would also mean that latency between the CPU and GPU would continue to grow, and what's displayed wouldn't at all reflect what the CPU is currently doing.
Thanks.
But It don't understand why in the while loop, the code can't return to the begin quickly unless after the last line code is executed, the thread is suspended by something.
I debug and find that the interval after execute the last line code(DWORD dwEndTime = timeGetTime();) and go back to the first line(DWORD dwStartTime = timeGetTime();) is about 25ms
How did you measure this? It makes no sense for Present to block, two lines of code after it's execution...

[quote name='moon2012' timestamp='1334290903' post='4930837']I debug and find that the interval after execute the last line code(DWORD dwEndTime = timeGetTime();) and go back to the first line(DWORD dwStartTime = timeGetTime();) is about 25ms
How did you measure this? It makes no sense for Present to block, two lines of code after it's execution...
[/quote]

dwStartTime of the second time - dwEndTime of the first time = 25ms.

This topic is closed to new replies.

Advertisement