Not logged in, Join Here! or Log In Below:  
 
News Articles Search    
 

 Home / General Programming / One DX9 app stutters when Task Manager updates, another doesn't. Why? Account Manager
 
Archive Notice: This thread is old and no longer active. It is here for reference purposes. This thread was created on an older version of the flipcode forums, before the site closed in 2005. Please keep that in mind as you view this thread, as many of the topics and opinions may be outdated.
 
AlexGibbs

April 05, 2005, 02:18 PM

I wrote a non-DirectX program that runs with two DirectX 9 games (App1 or App2). My MFC program has a dialog with a static control that updates twice a second. App1 runs smoothly with my program but App2 stutters when my program updates its control. My program uses 1% of the CPU when App1 is running but 30% of the CPU when App2 is running. My program is doing the same thing in both cases, so what could be different about App2 that causes this problem?

The same thing happens if I run the Windows Task Manager instead of my program. The CPU usage of Task Manager goes up with App2, and App2 stutters when Task Manager updates. This doesn't happen with App1.

The problem occurs whether my dialog is topmost or not. It occurs whether my dialog clips App2 or is off to the side. It occurs whether I update a static control or BitBlt a bitmap. The problem does NOT occur when I stop my dialog from updating. It does not occur when my dialog is minimized or covered up.

App2 does not like other windows updating. If I knew why then maybe I could figure out how to work around it. I'm running Windows XP Pro and DirectX 9.0c. Thanks in advance for suggestions as to the cause or even solutions!

Alex Gibbs

 
I'M BRIAN FELLOWS

April 05, 2005, 07:29 PM

APP2 SENDS A LOT OF WINDOWS MESSAGES.

 
Alex Gibbs

April 06, 2005, 02:09 AM

My explanation was pretty involved so here is a simpler case. I made a new MFC app that is just a normal dialog showing a counter that updates once a second (using WM_TIMER). Call it Counter. App1 and App2 are both DX9 games, not written by me.

- Run Counter. It's CPU use is < 1%.
- Run App1. Counter's CPU use is < 1%. App1 runs smoothly.
- Exit App1.
- Run App2. Counter's CPU use goes up, with peaks around 30%. App2 stutters or glitches exactly when Counter updates.
- Minimize or cover up Counter. Counter's CPU use goes back to < 1% and App2 runs smoothly.
- Replace all above occurances of "Counter" with "Windows Task Manager" and the results are basically the same.

Counter was always doing the same thing. The increased CPU use is the cause of the stuttering. But what is causing the increased CPU use that is being attributed to Counter? It seems to only occur when Counter is updating/painting while App2 is running. How is App2 causing the CPU use of Counter to increase?

"Mr. Fellows", I'm not really sure how App2's messages would make Counter's CPU use go up. Maybe by blocking messages from Counter? Microsoft Spy++ doesn't show any unusual messages to Counter or App2. Messages from App2 to Windows may be mucking up Windows though. I don't know how to tell what App2 is sending to Windows.

 
{FluffysWhole}

April 06, 2005, 03:50 AM

Your explaination implies to me that the problem is the locking of the DC that is the problem.

I would assume that App2 locks the DX device for longer then App1, and possibly almost constantly. Thus forcing your counter App to wait longer when calling Get/CreateDC() and App2 is running. This would cause your counter app to stall, when your counter app finally gets the dc this would then stall App2 from being able to update until your counter app calls Release/DeleteDC().

 
Endurion

April 07, 2005, 01:19 AM

App2 is not multi-app-friendly.

App1 behaves nice, if it's not active it does not constant updates, App2 just goes full speed whenever it can.

A multi-app-friendly app should have two message loops, one using PeekMessage for full speed ahead, and one using GetMessage for the non-active state.

 
AlexGibbs

April 07, 2005, 09:58 AM

I might as well say that App1 is EverQuest, App2 is EverQuest II, and my program is EQ Pixie (http://www.eqpixie.com).

FluffysWhole, that sounds reasonable. Below is the OnPaint for the control in my program. If I comment out the BitBlt then the problem goes away (no stutter and no high CPU use). Documentation for CPaintDC says "It performs a CWnd::BeginPaint at construction time and CWnd::EndPaint at destruction time", which should be when the DC is gotten/released. It looks like the DC isn't the problem and that the actual process of drawing is what leads to high CPU use when App2 is running.

  1. void CWndDerivedControl::OnPaint ()
  2. {
  3.   CPaintDC  cPaintDC (this);
  4.  
  5.   // Make absolutely sure optimization doesn't remove CPaintDC if I comment out the BitBlt.
  6.   if (!cPaintDC.GetSafeHdc ())
  7.     AfxMessageBox ("CPaintDC Error");
  8.   cPaintDC.BitBlt (0, 0, m_nWidth, m_nHeight, &m_dcPlot, 0, 0, SRCCOPY);
  9. }

Endurion, hmm, that may be true. I might be missing something but that doesn't explain why the CPU use of Task Manager or my program goes UP when App2 is running (leading to App2 stuttering). Your suggestion did make we wonder if there was any difference when App2 is the active window or not. It doesn't seem to matter.

Any other ideas? Thanks much.

 
criznach

April 07, 2005, 03:01 PM

App2 could be sync'd to the vertical blank which *may* be causing your app and others to delay drawing until the page flip. You might try and profile your OnPaint function - that's where it would hang. I know that the standard vblank wait calls spike CPU usage. I'm not sure what you can do about it, but that's my suspicion. Will app2 run in a window? What happens then?

 
psycode

April 07, 2005, 04:22 PM

I'm not sure if its relevant, but I've found the CPU usage in task manager to be unreliable in certain situations. Specifically, I wrote an app which displayed it's FPS and updated every 1ms, as it was only drawing a small area where the FPS is being reported it was achieving 1000fps. In task manager, it was reported as using less than 1% of the CPU which seems impossible, and the CPU usage of every other application had increased significantly.

I think that CPU usage in task manager is sampled at the end of every ms, so my application was being missed as it would be sleeping at the end of every ms because a frame was always being rendered in less than 1ms.

It seems unlikely that App2 is running at 1000fps, but it is possible that the CPU usage is basically incorrect. What is the kernel CPU usage (it can be enabled in the View menu)?

Either the CPU usage is incorrect, or the process of locking the DC for drawing performs some sort of polling, rather than a normal preemptive wait which would not use any CPU while waiting for a lock. I think that the DC may not be truly locked until the first operation on the DC is performed, which would explain why removing the BitBlt removed the problem.

 
This thread contains 8 messages.
 
 
Hosting by Solid Eight Studios, maker of PhotoTangler Collage Maker.