added --enable-rdtsc configure option to enhance timer performance, especially in virtualized environments; default disabled - credits to sirius_black
git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@14265 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
parent
2b305d5a62
commit
f9c60fd3fa
37
configure.in
37
configure.in
@ -74,6 +74,30 @@ AC_ARG_ENABLE(
|
||||
[enable_debug="no"]
|
||||
)
|
||||
|
||||
#
|
||||
# RDTSC as Tick Source
|
||||
#
|
||||
AC_ARG_ENABLE(
|
||||
[rdtsc],
|
||||
AC_HELP_STRING(
|
||||
[--enable-rdtsc],
|
||||
[
|
||||
Uses rdtsc as timing source (disabled by default)
|
||||
Enable it when you've timing issues.
|
||||
|
||||
(For example: in conjunction with XEN or Other Virtualization mechanisms)
|
||||
|
||||
Note:
|
||||
Please ensure that you've disabled dynamic CPU-Frequencys, such as power saving options.
|
||||
(On the most modern Dedicated Servers cpufreq is preconfigured, see your distribution's manual
|
||||
how to disable it)
|
||||
]
|
||||
),
|
||||
[
|
||||
enable_rdtsc=1
|
||||
],
|
||||
[enable_rdtsc=0]
|
||||
)
|
||||
|
||||
#
|
||||
# Profiler
|
||||
@ -383,6 +407,19 @@ case $enable_debug in
|
||||
esac
|
||||
|
||||
|
||||
#
|
||||
# RDTSC
|
||||
#
|
||||
case $enable_rdtsc in
|
||||
0)
|
||||
#default value
|
||||
;;
|
||||
1)
|
||||
CFLAGS="$CFLAGS -DENABLE_RDTSC"
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
#
|
||||
# Profiler
|
||||
#
|
||||
|
@ -100,11 +100,52 @@ char* search_timer_func_list(TimerFunc func)
|
||||
* Get tick time
|
||||
*----------------------------*/
|
||||
|
||||
#if defined(ENABLE_RDTSC)
|
||||
static uint64 RDTSC_BEGINTICK = 0, RDTSC_CLOCK = 0;
|
||||
|
||||
static __inline uint64 _rdtsc(){
|
||||
register union{
|
||||
uint64 qw;
|
||||
uint32 dw[2];
|
||||
} t;
|
||||
|
||||
asm volatile("rdtsc":"=a"(t.dw[0]), "=d"(t.dw[1]) );
|
||||
|
||||
return t.qw;
|
||||
}
|
||||
|
||||
static void rdtsc_calibrate(){
|
||||
uint64 t1, t2;
|
||||
int32 i;
|
||||
|
||||
ShowStatus("Calibrating Timer Source, please wait... ");
|
||||
|
||||
RDTSC_CLOCK = 0;
|
||||
|
||||
for(i = 0; i < 5; i++){
|
||||
t1 = _rdtsc();
|
||||
usleep(1000000); //1000 MS
|
||||
t2 = _rdtsc();
|
||||
RDTSC_CLOCK += (t2 - t1) / 1000;
|
||||
}
|
||||
RDTSC_CLOCK /= 5;
|
||||
|
||||
RDTSC_BEGINTICK = _rdtsc();
|
||||
|
||||
ShowMessage(" done. (Frequency: %u Mhz)\n", (uint32)(RDTSC_CLOCK/1000) );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/// platform-abstracted tick retrieval
|
||||
static unsigned int tick(void)
|
||||
{
|
||||
#if defined(WIN32)
|
||||
return GetTickCount();
|
||||
#elif defined(ENABLE_RDTSC)
|
||||
//
|
||||
return (unsigned int)((_rdtsc() - RDTSC_BEGINTICK) / RDTSC_CLOCK);
|
||||
//
|
||||
#elif (defined(_POSIX_TIMERS) && _POSIX_TIMERS > 0 && defined(_POSIX_MONOTONIC_CLOCK) /* posix compliant */) || (defined(__FreeBSD_cc_version) && __FreeBSD_cc_version >= 500005 /* FreeBSD >= 5.1.0 */)
|
||||
struct timespec tval;
|
||||
clock_gettime(CLOCK_MONOTONIC, &tval);
|
||||
@ -368,6 +409,10 @@ unsigned long get_uptime(void)
|
||||
|
||||
void timer_init(void)
|
||||
{
|
||||
#if defined(ENABLE_RDTSC)
|
||||
rdtsc_calibrate();
|
||||
#endif
|
||||
|
||||
time(&start_time);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user