Changeset - r3341:9e6b46ee7ba7
[Not reviewed]
master
0 7 1
Darkvater - 18 years ago 2006-03-26 21:15:09
darkvater@openttd.org
(svn r4125) - Feature: Add a general TIC() TOC() mechanism using rdtsc or something similar on non-i386 architectures to performance-tune (critical) code. Some systems are probably missing, but those can be added later.
8 files changed with 106 insertions and 51 deletions:
0 comments (0 inline, 0 general)
Makefile
Show inline comments
 
@@ -670,6 +670,7 @@ SRCS += oldloader.c
 
SRCS += openttd.c
 
SRCS += order_cmd.c
 
SRCS += order_gui.c
 
SRCS += os_timer.c
 
SRCS += pathfind.c
 
SRCS += player_gui.c
 
SRCS += players.c
debug.h
Show inline comments
 
@@ -26,4 +26,27 @@ void CDECL debug(const char *s, ...);
 
void SetDebugString(const char *s);
 
const char *GetDebugString(void);
 

	
 
/* MSVC of course has to have a different syntax for long long *sigh* */
 
#ifdef _MSC_VER
 
# define OTTD_PRINTF64 "I64"
 
#else
 
# define OTTD_PRINTF64 "ll"
 
#endif
 

	
 
// Used for profiling
 
#define TIC() {\
 
	extern uint64 _rdtsc(void);\
 
	uint64 _xxx_ = _rdtsc();\
 
	static uint64 __sum__ = 0;\
 
	static uint32 __i__ = 0;
 

	
 
#define TOC(str, count)\
 
	__sum__ += _rdtsc() - _xxx_;\
 
	if (++__i__ == count) {\
 
		printf("[%s]: %" OTTD_PRINTF64 "u [avg: %.1f]\n", str, __sum__, __sum__/(double)__i__);\
 
		__i__ = 0;\
 
		__sum__ = 0;\
 
	}\
 
}
 

	
 
#endif /* DEBUG_H */
functions.h
Show inline comments
 
@@ -116,12 +116,6 @@ static inline TileIndex RandomTile(void)
 
uint32 InteractiveRandom(void); /* Used for random sequences that are not the same on the other end of the multiplayer link */
 
uint InteractiveRandomRange(uint max);
 

	
 

	
 
// Used for profiling
 
#define TIC() { extern uint32 _rdtsc(void); uint32 _xxx_ = _rdtsc(); static float __avg__;
 
#define TOC(s) 	_xxx_ = _rdtsc() - _xxx_; __avg__=__avg__*0.99+_xxx_*0.01; printf("%s: %8d %f\n", s, _xxx_,__avg__); }
 

	
 

	
 
void SetDate(uint date);
 
/* facedraw.c */
 
void DrawPlayerFace(uint32 face, int color, int x, int y);
openttd.dsp
Show inline comments
 
@@ -339,6 +339,12 @@ SOURCE=.\ottdres.rc
 
# End Source File
 
# Begin Source File
 

	
 
SOURCE=.\os_timer.c
 
# End Source File
 
# Begin Source File
 

	
 
# Begin Source File
 

	
 
SOURCE=.\pathfind.c
 
# End Source File
 
# Begin Source File
openttd.vcproj
Show inline comments
 
@@ -299,6 +299,9 @@
 
				RelativePath=".\ottdres.rc">
 
			</File>
 
			<File
 
				RelativePath=".\os_timer.c">
 
			</File>
 
			<File
 
				RelativePath=".\pathfind.c">
 
			</File>
 
			<File
os_timer.c
Show inline comments
 
new file 100644
 
#include "stdafx.h"
 
 
#undef RDTSC_AVAILABLE
 
 
/* rdtsc for MSC_VER, uses simple inline assembly, or _rdtsc
 
 * from external win64.asm because VS2005 does not support inline assembly */
 
#if defined(_MSC_VER) && !defined(RDTSC_AVAILABLE)
 
# if defined (_M_AMD64)
 
extern uint64 _rdtsc(void);
 
#	else
 
uint64 _declspec(naked) _rdtsc(void) 
 
{
 
	_asm {
 
		rdtsc
 
		ret
 
	}
 
}
 
# endif
 
# define RDTSC_AVAILABLE
 
#endif
 
 
/* rdtsc for OS/2. Hopefully this works, who knows */
 
#if defined (__WATCOMC__) && !defined(RDTSC_AVAILABLE)
 
unsigned __int64 _rdtsc( void);
 
# pragma aux _rdtsc = 0x0F 0x31 value [edx eax] parm nomemory modify exact [edx eax] nomemory;
 
# define RDTSC_AVAILABLE
 
#endif
 
 
/* rdtsc for all other *nix-en (hopefully). Use GCC syntax */
 
#if defined(__i386__) || defined(__x86_64__) && !defined(RDTSC_AVAILABLE)
 
uint64 _rdtsc(void)
 
{
 
	uint32 high, low;
 
	__asm__ __volatile__ ("rdtsc" : "=a" (low), "=d" (high));
 
	return ((uint64)high << 32) | low;
 
}
 
# define RDTSC_AVAILABLE
 
#endif
 
 
/* rdtsc for PPC which has this not */
 
#if defined(__POWERPC__) && !defined(RDTSC_AVAILABLE)
 
uint64 _rdtsc(void)
 
{
 
	uint32 high, low;
 
	uint32 high2 = 0;
 
	/* PPC does not have rdtsc, so we cheat by reading the two 32-bit time-counters
 
	 * it has, 'Move From Time Base (Upper)'. Since these are two reads, in the
 
	 * very unlikely event that the lower part overflows to the upper part while we
 
	 * read it; we double-check and reread the registers */
 
	asm volatile (
 
				  "mftbu %0\n"
 
				  "mftb %1\n"
 
				  "mftbu %2\n"
 
				  "cmpw %3,%4\n"
 
				  "bne- $-16\n"
 
				  : "=r" (high), "=r" (low), "=r" (high2)
 
				  : "0" (high), "2" (high2)
 
				  );
 
	return ((uint64)high << 32) | low;
 
}
 
# define RDTSC_AVAILABLE
 
#endif
 
 
/* In all other cases we have no support for rdtsc. No major issue,
 
 * you just won't be able to profile your code with TIC()/TOC() */
 
#if !defined(RDTSC_AVAILABLE)
 
#warning "OS has no support for rdtsc()"
 
uint64 _rdtsc(void) {return 0;}
 
#endif
train_cmd.c
Show inline comments
 
@@ -2087,29 +2087,6 @@ static const byte _search_directions[6][
 
};
 

	
 
static const byte _pick_track_table[6] = {1, 3, 2, 2, 0, 0};
 
#ifdef PF_BENCHMARK
 
#if !defined(_MSC_VER)
 
unsigned int _rdtsc()
 
{
 
	unsigned int high, low;
 

	
 
	__asm__ __volatile__ ("rdtsc" : "=a" (low), "=d" (high));
 
	return low;
 
}
 
#else
 
#ifndef _M_AMD64
 
static unsigned int _declspec(naked) _rdtsc(void)
 
{
 
	_asm {
 
		rdtsc
 
		ret
 
	}
 
}
 
#endif
 
#endif
 
#endif
 

	
 

	
 

	
 
/* choose a track */
 
static byte ChooseTrainTrack(Vehicle* v, TileIndex tile, DiagDirection enterdir, TrackdirBits trackdirbits)
 
@@ -2117,8 +2094,7 @@ static byte ChooseTrainTrack(Vehicle* v,
 
	TrainTrackFollowerData fd;
 
	uint best_track;
 
#ifdef PF_BENCHMARK
 
	int time = _rdtsc();
 
	static float f;
 
	TIC()
 
#endif
 

	
 
	assert((trackdirbits & ~0x3F) == 0);
 
@@ -2171,9 +2147,7 @@ static byte ChooseTrainTrack(Vehicle* v,
 
	}
 

	
 
#ifdef PF_BENCHMARK
 
	time = _rdtsc() - time;
 
	f = f * 0.99 + 0.01 * time;
 
	printf("PF time = %d %f\n", time, f);
 
	TOC("PF time = ", 1)
 
#endif
 

	
 
	return best_track;
win32.c
Show inline comments
 
@@ -62,11 +62,6 @@ bool LoadLibraryList(Function proc[], co
 
}
 

	
 
#ifdef _MSC_VER
 
#	ifdef _M_AMD64
 
void* _get_save_esp(void);
 
uint64 _rdtsc(void);
 
#	endif
 

	
 
static const char *_exception_string;
 
#endif
 

	
 
@@ -594,6 +589,7 @@ static LONG WINAPI ExceptionHandler(EXCE
 
static void Win32InitializeExceptions(void)
 
{
 
#ifdef _M_AMD64
 
	extern void *_get_save_esp(void);
 
	_safe_esp = _get_save_esp();
 
#else
 
	_asm {
 
@@ -603,7 +599,7 @@ static void Win32InitializeExceptions(vo
 

	
 
	SetUnhandledExceptionFilter(ExceptionHandler);
 
}
 
#endif
 
#endif /* _MSC_VER */
 

	
 
static char *_fios_path;
 
static char *_fios_save_path;
 
@@ -1057,17 +1053,6 @@ static int ParseCommandLine(char *line, 
 
	return n;
 
}
 

	
 

	
 
#if defined(_MSC_VER) && !defined(_M_AMD64)
 
uint64 _declspec(naked) _rdtsc(void)
 
{
 
	_asm {
 
		rdtsc
 
		ret
 
	}
 
}
 
#endif
 

	
 
void CreateConsole(void)
 
{
 
	HANDLE hand;
0 comments (0 inline, 0 general)