Release Version is Slower Than Debug!

Started by
11 comments, last by Justin Nixon 21 years, 9 months ago
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]
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.
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.
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

Simon O'Connor | Technical Director (Newcastle) Lockwood Publishing | LinkedIn | Personal site

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.											}  
Sorry, forgot to enter my user name.

Justin.
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.
- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
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.
Editor42 ...builds worlds
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.
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]

This topic is closed to new replies.

Advertisement