• Advertisement

Archived

This topic is now archived and is closed to further replies.

Release Version is Slower Than Debug!

This topic is 5684 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I am having a very strange and bizarre problem with a project. When I compile and run the debug version, the FPS is 20% better than the release version! Does anyone know why this should be so? I've looked at the control panel settings and they appear to be correct (use retail version). I've also looked at the compiler settings, and they are set to compile the fastest code. I'm using the DX8.0 SDK. Thanks, Justin. [edited by - Justin Nixon on June 29, 2002 12:55:07 PM]

Share this post


Link to post
Share on other sites
Advertisement
are you correctly initing structs and varibles? in release they contain garbage and not automatically zero like in debug mode.

is your framerate counter correctly counting time?

are you using multithreading? if so are you make sure you give up some time for the other threads?

are you correctly handling windows messages?

its most likly you are not doing things that are done by the debug release so things get wonky in release mode. its also likly that your project settings may be wrong. for instance are you could be telling the compiler to inline functions that should not be inlined.

are you doing are using any ocde you did not write? if so are you using it correctly? are you doing anything abnormal with respect to anything?

i really think its your framerate counting not working correctly or possibly even vsync throwing your framerate off.

Share this post


Link to post
Share on other sites
Does the settings for Debug and Release match? Perhaps you have optimized the Debug, but forgot to do the same on the Release? Remember that the two settings (and any other) are totally independent of eachother.

Share this post


Link to post
Share on other sites
Run using the debug version with the output level slider on maximum and check your debug output window afterwards.

The debug D3D runtime sometimes corrects common small mistakes in use of D3D and then outputs a warning/error to the debug output window to tell you.

The release/retail D3D doesn''t do this so mistakes in your code get passed on - and could be causing slowness.

Also are you using a PURE device ? - if so, check for any Get* style calls in your code or in code you call (e.g. D3DX)

--
Simon O''Connor
Creative Asylum Ltd
www.creative-asylum.com

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Thanks for all the replies, I''ll try all those ideas. I think my FPS calculations are correct as the debug version has smoother animation.

One that struck me was multi-threading being a possible cause. I am using multi-threading so I can seperate message handling from the rest of the program. This is the way I''m handling messages:


  

Simulator Simulator(Direct3D.GetDevice(), &Keyboard); // Declare the simulator.


_beginthread(SimulatorThread, 0, &Simulator); // Start simulator thread.


WaitMessage(); // Suspend the message loop thread so that it does not unduly draw processor power away from the Simulator thread.


while(GetMessage(&Message, NULL, 0, 0)) // Message loop...

{
DispatchMessage(&Message);
WaitMessage(); // Once again, effectively put this thread to sleep to be awoken only when there''s a message to be dealt with.

}

void SimulatorThread(void *pArgList)
{
Simulator *pSimulator=(Simulator *)pArgList; // Cast the pointer.


pSimulator->Proceed(); // Start the simulator.


PostMessage(ghWnd, WM_CLOSE, 0, 0); // The simulator has ended, so send a message to terminate the message loop.


_endthread(); // Terminate the Simulator thread.

}

Share this post


Link to post
Share on other sites
Do you tell DirectX that you''re threading?
There''s a number of things you need to do to make Dx happy in an MT''ed situation.
Again, running with the debug build of DirectX will likely shed some light.

Share this post


Link to post
Share on other sites
And be carefull with multithreading and debug.
With debug, most variables become thread safe and it''s not the case in release. It could end up in a synchronization lock or bottleneck.

Share this post


Link to post
Share on other sites
I''ll show you my entire WinMain file:


  

// WinMain.cpp

// COPYRIGHT 2002 JUSTIN NIXON


// This application uses the dual-thread approach to greatly ease Windows message handling.



// Additional libraries required...

#pragma comment (lib, "d3dx8")
#pragma comment (lib, "d3d8")
#pragma comment (lib, "dinput8")
#pragma comment (lib, "dxguid")
#pragma comment (lib, "d3dxof")
#pragma comment (lib, "winmm")


// Standard includes...

#include <process.h>
#include <stdio.h>
#include <d3d8.h>
#include <dinput.h>


// Application includes...

#include "Window.h"
#include "Direct3D.h"
#include "DirectInput.h"
#include "Simulator.h"



// GLOBALS...

LRESULT CALLBACK WinProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow);
void SimulatorThread(void *);

HWND ghWnd;


// FUNCTIONS...

LRESULT CALLBACK WinProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_CLOSE:
PostQuitMessage(0);
return(false);

default:
return(DefWindowProc(hWnd, uMsg, wParam, lParam)); // Pass all unhandled messages to ''DefWindowProc''.

}
}


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
MSG Message;


Window Window;

if(Window.Open(hInstance)) // Open window.

{
ghWnd=Window.GetHandle();
Direct3D Direct3D;

if(Direct3D.Open(ghWnd, SCREEN_WIDTH, SCREEN_HEIGHT, D3DFMT_X8R8G8B8, D3DFMT_D24S8)) // Open Direct3D.

{
IDirectInput8 *pDirectInput=false;

if(DirectInput8Create(hInstance, DIRECTINPUT_VERSION, IID_IDirectInput8, (void **)&pDirectInput, false)==DI_OK) // Open DirectInput.

{
Keyboard Keyboard;

if(Keyboard.Open(pDirectInput, ghWnd)) // Open the keyboard device.

{
Simulator Simulator(Direct3D.GetDevice(), &Keyboard); // Declare the simulator.


_beginthread(SimulatorThread, 0, &Simulator); // Start simulator thread.


WaitMessage(); // Suspend the message loop thread so that it does not unduly draw processor power away from the Simulator thread.


while(GetMessage(&Message, NULL, 0, 0)) // Message loop...

{
DispatchMessage(&Message);
WaitMessage(); // Once again, effectively put this thread to sleep to be awoken only when there''s a message to be dealt with.

}

Keyboard.Close(); // Simulator ended - begin to clean up.

}

pDirectInput->Release(); // Release DirectInput.

}

Direct3D.Close(); // Close Direct3D.

}

Window.Close(hInstance); // Close window.

}


return(Message.wParam); // End of program.

}


void SimulatorThread(void *pArgList)
{
Simulator *pSimulator=(Simulator *)pArgList; // Cast the pointer.


pSimulator->Proceed(); // Start the simulator.


PostMessage(ghWnd, WM_CLOSE, 0, 0); // The simulator has ended, so send a message to terminate the message loop.


_endthread(); // Terminate the Simulator thread.

}



Could the way I''m handling messages be the cause? As I interprete the SDK docs, it shouldn''t - I don''t think my program is breaking any rules. BTW, it makes no difference to FPS whether inform Direct3D of multi-threading or not.

DX8.0 SDK Documentation:

Multithreading Issues

Full-screen Microsoft® Direct3D® applications provide a window handle to the Direct3D run time. The window is hooked by the run time. This means that all messages passed to the application''s window message procedure have first been examined by the Direct3D run time''s own message-handling procedure.

Display mode changes are affected by support routines built into the underlying operating system. When mode changes occur, the system broadcasts several messages to all applications. In Direct3D applications, the messages are received on the window procedure thread, which is not necessarily the same thread that called IDirect3DDevice8::Reset or IDirect3D8::CreateDevice (or the final IUnknown::Release of IDirect3DDevice8, which can cause a display mode change). The Direct3D run time maintains several critical sections internally. Because at least one of these critical sections is held across the mode switch caused by Reset or CreateDevice, these critical sections are still held when the application receives the mode-change related window messages.

This design has some implications for multithreaded applications. In particular, an application must be sure to strongly segregate its window message handling threads from its Direct3D threads. An application that causes a mode change on one thread but makes Direct3D calls on a different thread in its window procedure is in danger of deadlock.

For these reasons, Direct3D is designed so that the methods Reset, CreateDevice, TestCoorperativeLevel, or the final Release of IDirect3DDevice8 can only be called from the same thread that handles window messages.



I think the problem is somewhere else, no doubt some stupid mistake. I''ll let you know if I find it.

Again, thanks for everyone''s help.

Justin.

Share this post


Link to post
Share on other sites
simply put your simulator thread is not giving any time to your message pump. this causes stalls in processing input as well as other problems (ie batches of messages being processed thus stutters). put everything in one thread, i see no reason (ie performence benefit) for using multithreading in your situtaion.

add a Sleep(0) in your simulation loop (ie in the pSimulator->Proceed(); funtion). make sure its in your main look that gets called each frame.

if your running in windowed mode, you definatly will have major problems. your not easing windows message handling.

look up PeekMessage() and fixed timestep loops. commercial games dont use this technique, why should you?

also make sure your not using QueryPerformenceCounter(), there are problems with it. this can causes a jump in time of seconds (thus a stutter in animation). use timeGetTime() instead. its accurate to 1ms which should be plenty, and does not have this problem.


[edited by - a person on June 30, 2002 8:05:56 PM]

Share this post


Link to post
Share on other sites
Long time ago, I used similar method for handling messages but with DirectDraw. I used a seperate thread for handling messages and another thread for the rest of the game. I don''t remember that I had problems with debug and release, but I had another problem also related to performance. Whenever I press a key (and keep it pressed) the FPS drops down. I went to the keyboard settings in the control panel and slowed down the keyboard and tried the game again. As expected, there was no drop in FPS this time. I realized that whenever a message comes into the message queue, the processor switches between the two threads and this stalls performance (of course a single message won''t affect the performance, but hundreds of them will). Of course I could notice the difference at that time because it was only a 486. I ended up putting everything in the main thread and this time messages did not affect the performance.

Share this post


Link to post
Share on other sites
Thanks for the additional replies. I’ll update you on the things I’ve tried.

I’m already using timeGetTime() to calculate performance. My program is also using full screen mode. The keyboard trick didn’t work.

Not giving enough time for my message pump? The idea is that it is awoken only when there’s a message for it and then deals with it with GetMessage(). I have since removed the WaitMessage() calls because I now realise they’re probably not necessary (I’m assuming GetMessage() also puts the thread to sleep), but it made no difference anyway. PeekMessage() isn’t required when you have a separate message loop.

Even if the dual-thread approach is causing a slow down - which it isn’t, at least not a noticeable one - no one’s explained why the debug version should be 20% faster. This is why I am reluctant to accept many of the explanations.

I’m not going to give up the dual-thread approach (originally found in an article on the GameDev site), because it makes programming a real-time application so much easier, and I’m certain it’s not the problem.

There is something strange going on in my simulator thread. As S1CA mentioned earlier, it could be a coding error, which is captured by Direct3D in debug mode but not in release mode and ultimately results in a slowdown.

Thanks.

Justin.



[edited by - Justin Nixon on July 1, 2002 3:18:39 PM]

Share this post


Link to post
Share on other sites
Have you tried profiling or just adding timers to find out which areas of your app are taking longer between builds?

Share this post


Link to post
Share on other sites

  • Advertisement