Commit e2a34cbf authored by Marc Alff's avatar Marc Alff

WL#2373 Use cycle counter for timing

parent 23159440
dnl -*- ksh -*- dnl -*- ksh -*-
dnl Process this file with autoconf to produce a configure script. dnl Process this file with autoconf to produce a configure script.
# Copyright (C) 2008-2009 Sun Microsystems, Inc
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
AC_PREREQ(2.52)dnl Minimum Autoconf version required. AC_PREREQ(2.52)dnl Minimum Autoconf version required.
AC_INIT(sql/mysqld.cc) AC_INIT(sql/mysqld.cc)
...@@ -2916,7 +2931,54 @@ case $SYSTEM_TYPE in ...@@ -2916,7 +2931,54 @@ case $SYSTEM_TYPE in
esac esac
AC_SUBST(MAKE_BINARY_DISTRIBUTION_OPTIONS) AC_SUBST(MAKE_BINARY_DISTRIBUTION_OPTIONS)
#--------------------------------------------------------------------
# Support for WL#2373 (Use cycle counter for timing)
#--------------------------------------------------------------------
AC_CHECK_HEADERS(time.h)
AC_CHECK_HEADERS(sys/time.h)
AC_CHECK_HEADERS(sys/times.h)
AC_CHECK_HEADERS(asm/msr.h)
#msr.h has rdtscll()
AC_CHECK_HEADERS(ia64intrin.h)
AC_CHECK_FUNCS(times)
AC_CHECK_FUNCS(gettimeofday)
AC_CHECK_FUNCS(read_real_time)
# This should work on AIX.
AC_CHECK_FUNCS(ftime)
# This is still a normal call for milliseconds.
AC_CHECK_FUNCS(time)
# We can use time() on Macintosh if there is no ftime().
AC_CHECK_FUNCS(rdtscll)
# I doubt that we'll ever reach the check for this.
# When compiling with Sun Studio C / C++ we need to include
# my_timer_cycles.il, an "inline templates" separate file,
# on the command line. It has assembly code, "rd %tick" for
# SPARC or "rdtsc" for x86.
RDTSC_SPARC_ASSEMBLY=""
case $CC_VERSION in
*Sun*C*)
RDTSC_SPARC_ASSEMBLY="my_timer_cycles.il"
;;
esac
case $CXX_VERSION in
*Sun*C++*)
RDTSC_SPARC_ASSEMBLY="my_timer_cycles.il"
;;
esac
AC_SUBST([RDTSC_SPARC_ASSEMBLY])
#--------------------------------------------------------------------
# Output results # Output results
#--------------------------------------------------------------------
if test -d "$srcdir/pstack" ; then if test -d "$srcdir/pstack" ; then
AC_CONFIG_FILES(pstack/Makefile pstack/aout/Makefile) AC_CONFIG_FILES(pstack/Makefile pstack/aout/Makefile)
fi fi
......
...@@ -38,6 +38,7 @@ noinst_HEADERS = config-win.h config-netware.h lf.h my_bit.h \ ...@@ -38,6 +38,7 @@ noinst_HEADERS = config-win.h config-netware.h lf.h my_bit.h \
my_aes.h my_tree.h my_trie.h hash.h thr_alarm.h \ my_aes.h my_tree.h my_trie.h hash.h thr_alarm.h \
thr_lock.h t_ctype.h violite.h my_md5.h base64.h \ thr_lock.h t_ctype.h violite.h my_md5.h base64.h \
my_handler.h my_time.h service_versions.h \ my_handler.h my_time.h service_versions.h \
my_rdtsc.h \
my_vle.h my_user.h my_atomic.h atomic/nolock.h \ my_vle.h my_user.h my_atomic.h atomic/nolock.h \
atomic/rwlock.h atomic/x86-gcc.h atomic/generic-msvc.h \ atomic/rwlock.h atomic/x86-gcc.h atomic/generic-msvc.h \
atomic/gcc_builtins.h my_libwrap.h my_stacktrace.h \ atomic/gcc_builtins.h my_libwrap.h my_stacktrace.h \
......
/* Copyright (C) 2008, 2009 Sun Microsystems, Inc
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
rdtsc3 -- multi-platform timer code
pgulutzan@mysql.com, 2005-08-29
modified 2008-11-02
*/
#ifndef MY_RDTSC_H
#define MY_RDTSC_H
/**
Characteristics of a timer.
*/
struct my_timer_unit_info
{
/** Routine used for the timer. */
ulonglong routine;
/** Overhead of the timer. */
ulonglong overhead;
/** Frequency of the timer. */
ulonglong frequency;
/** Resolution of the timer. */
ulonglong resolution;
};
/**
Characteristics of all the supported timers.
@sa my_timer_init().
*/
struct my_timer_info
{
/** Characteristics of the cycle timer. */
struct my_timer_unit_info cycles;
/** Characteristics of the nanosecond timer. */
struct my_timer_unit_info nanoseconds;
/** Characteristics of the microsecond timer. */
struct my_timer_unit_info microseconds;
/** Characteristics of the millisecond timer. */
struct my_timer_unit_info milliseconds;
/** Characteristics of the tick timer. */
struct my_timer_unit_info ticks;
};
typedef struct my_timer_info MY_TIMER_INFO;
C_MODE_START
/**
A cycle timer.
@return the current timer value, in cycles.
*/
ulonglong my_timer_cycles(void);
/**
A namoseconds timer.
@return the current timer value, in nanoseconds.
*/
ulonglong my_timer_nanoseconds(void);
/**
A microseconds timer.
@return the current timer value, in microseconds.
*/
ulonglong my_timer_microseconds(void);
/**
A millisecond timer.
@return the current timer value, in milliseconds.
*/
ulonglong my_timer_milliseconds(void);
/**
A ticks timer.
@return the current timer value, in ticks.
*/
ulonglong my_timer_ticks(void);
/**
Timer initialization function.
@param [out] mti the timer characteristics.
*/
void my_timer_init(MY_TIMER_INFO *mti);
C_MODE_END
#define MY_TIMER_ROUTINE_ASM_X86 1
#define MY_TIMER_ROUTINE_ASM_X86_64 2
#define MY_TIMER_ROUTINE_RDTSCLL 3
#define MY_TIMER_ROUTINE_ASM_X86_WIN 4
#define MY_TIMER_ROUTINE_RDTSC 5
#define MY_TIMER_ROUTINE_ASM_IA64 6
#define MY_TIMER_ROUTINE_ASM_PPC 7
#define MY_TIMER_ROUTINE_SGI_CYCLE 8
#define MY_TIMER_ROUTINE_GETHRTIME 9
#define MY_TIMER_ROUTINE_READ_REAL_TIME 10
#define MY_TIMER_ROUTINE_CLOCK_GETTIME 11
#define MY_TIMER_ROUTINE_NXGETTIME 12
#define MY_TIMER_ROUTINE_GETTIMEOFDAY 13
#define MY_TIMER_ROUTINE_QUERYPERFORMANCECOUNTER 14
#define MY_TIMER_ROUTINE_GETTICKCOUNT 15
#define MY_TIMER_ROUTINE_TIME 16
#define MY_TIMER_ROUTINE_TIMES 17
#define MY_TIMER_ROUTINE_FTIME 18
#define MY_TIMER_ROUTINE_ASM_PPC64 19
#define MY_TIMER_ROUTINE_ASM_SUNPRO_SPARC64 20
#define MY_TIMER_ROUTINE_ASM_SUNPRO_SPARC32 21
#define MY_TIMER_ROUTINE_ASM_SUNPRO_I386 22
#define MY_TIMER_ROUTINE_ASM_GCC_SPARC64 23
#define MY_TIMER_ROUTINE_ASM_GCC_SPARC32 24
#define MY_TIMER_ROUTINE_MACH_ABSOLUTE_TIME 25
#define MY_TIMER_ROUTINE_GETSYSTEMTIMEASFILETIME 26
#define MY_TIMER_ROUTINE_ASM_SUNPRO_X86_64 27
#endif
# Copyright (C) 2006 MySQL AB # Copyright (C) 2006 MySQL AB, 2009 Sun Microsystems, Inc
# #
# This program is free software; you can redistribute it and/or modify # This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
...@@ -41,7 +41,8 @@ SET(MYSYS_SOURCES array.c charset-def.c charset.c checksum.c default.c default_ ...@@ -41,7 +41,8 @@ SET(MYSYS_SOURCES array.c charset-def.c charset.c checksum.c default.c default_
rijndael.c safemalloc.c sha1.c string.c thr_alarm.c thr_lock.c thr_mutex.c rijndael.c safemalloc.c sha1.c string.c thr_alarm.c thr_lock.c thr_mutex.c
thr_rwlock.c tree.c typelib.c my_vle.c base64.c my_memmem.c my_getpagesize.c thr_rwlock.c tree.c typelib.c my_vle.c base64.c my_memmem.c my_getpagesize.c
lf_alloc-pin.c lf_dynarray.c lf_hash.c lf_alloc-pin.c lf_dynarray.c lf_hash.c
my_atomic.c my_getncpus.c) my_atomic.c my_getncpus.c
my_rdtsc.c)
IF(NOT SOURCE_SUBLIBS) IF(NOT SOURCE_SUBLIBS)
ADD_LIBRARY(mysys ${MYSYS_SOURCES}) ADD_LIBRARY(mysys ${MYSYS_SOURCES})
......
...@@ -16,7 +16,8 @@ ...@@ -16,7 +16,8 @@
MYSQLDATAdir = $(localstatedir) MYSQLDATAdir = $(localstatedir)
MYSQLSHAREdir = $(pkgdatadir) MYSQLSHAREdir = $(pkgdatadir)
MYSQLBASEdir= $(prefix) MYSQLBASEdir= $(prefix)
INCLUDES = @ZLIB_INCLUDES@ -I$(top_builddir)/include \ INCLUDES = @ZLIB_INCLUDES@ @RDTSC_SPARC_ASSEMBLY@ \
-I$(top_builddir)/include \
-I$(top_srcdir)/include -I$(srcdir) -I$(top_srcdir)/include -I$(srcdir)
pkglib_LIBRARIES = libmysys.a pkglib_LIBRARIES = libmysys.a
LDADD = libmysys.a $(top_builddir)/strings/libmystrings.a $(top_builddir)/dbug/libdbug.a LDADD = libmysys.a $(top_builddir)/strings/libmystrings.a $(top_builddir)/dbug/libdbug.a
...@@ -53,7 +54,8 @@ libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c my_mmap.c \ ...@@ -53,7 +54,8 @@ libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c my_mmap.c \
my_gethostbyname.c rijndael.c my_aes.c sha1.c \ my_gethostbyname.c rijndael.c my_aes.c sha1.c \
my_handler.c my_netware.c my_largepage.c \ my_handler.c my_netware.c my_largepage.c \
my_memmem.c stacktrace.c \ my_memmem.c stacktrace.c \
my_windac.c my_access.c base64.c my_libwrap.c my_windac.c my_access.c base64.c my_libwrap.c \
my_rdtsc.c
if NEED_THREAD if NEED_THREAD
# mf_keycache is used only in the server, so it is safe to leave the file # mf_keycache is used only in the server, so it is safe to leave the file
...@@ -65,7 +67,9 @@ endif ...@@ -65,7 +67,9 @@ endif
EXTRA_DIST = thr_alarm.c thr_lock.c my_pthread.c my_thr_init.c \ EXTRA_DIST = thr_alarm.c thr_lock.c my_pthread.c my_thr_init.c \
thr_mutex.c thr_rwlock.c \ thr_mutex.c thr_rwlock.c \
CMakeLists.txt mf_soundex.c \ CMakeLists.txt mf_soundex.c \
my_conio.c my_wincond.c my_winthread.c my_winerr.c my_winfile.c my_conio.c my_wincond.c my_winthread.c my_winerr.c \
my_winfile.c \
my_timer_cycles.il
libmysys_a_LIBADD = @THREAD_LOBJECTS@ libmysys_a_LIBADD = @THREAD_LOBJECTS@
# test_dir_DEPENDENCIES= $(LIBRARIES) # test_dir_DEPENDENCIES= $(LIBRARIES)
# testhash_DEPENDENCIES= $(LIBRARIES) # testhash_DEPENDENCIES= $(LIBRARIES)
......
This diff is collapsed.
/* Copyright (C) 2008 Sun Microsystems, Inc
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Sun Studio SPARC inline templates for cycle timer */
/* Sun Studio i386 and x86_64 inline templates for cycle timer */
/* I didn't say ".volatile" or ".nonvolatile". */
.inline my_timer_cycles_il_sparc64,0
rd %tick,%o0
.end
.inline my_timer_cycles_il_sparc32,0
rd %tick,%o2
srlx %o2,32,%o0
sra %o2,0,%o1
.end
.inline my_timer_cycles_il_i386,0
rdtsc
.end
.inline my_timer_cycles_il_x86_64,0
rdtsc
shlq $32,%rdx
orq %rdx,%rax
.end
# Copyright (C) 2007 MySQL AB, 2008-2009 Sun Microsystems, Inc
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/zlib
${CMAKE_SOURCE_DIR}/sql
${CMAKE_SOURCE_DIR}/regex
${CMAKE_SOURCE_DIR}/extra/yassl/include
${CMAKE_SOURCE_DIR}/unittest/mytap)
ADD_EXECUTABLE(bitmap-t bitmap-t.c)
TARGET_LINK_LIBRARIES(bitmap-t mytap mysys dbug strings)
ADD_EXECUTABLE(base64-t base64-t.c)
TARGET_LINK_LIBRARIES(base64-t mytap mysys dbug strings)
ADD_EXECUTABLE(my_atomic-t my_atomic-t.c)
TARGET_LINK_LIBRARIES(my_atomic-t mytap mysys dbug strings)
ADD_EXECUTABLE(lf-t lf-t.c)
TARGET_LINK_LIBRARIES(lf-t mytap mysys dbug strings)
ADD_EXECUTABLE(my_rdtsc-t my_rdtsc-t.c)
TARGET_LINK_LIBRARIES(my_rdtsc-t mytap mysys dbug strings)
...@@ -23,7 +23,7 @@ LDADD = $(top_builddir)/unittest/mytap/libmytap.a \ ...@@ -23,7 +23,7 @@ LDADD = $(top_builddir)/unittest/mytap/libmytap.a \
$(top_builddir)/dbug/libdbug.a \ $(top_builddir)/dbug/libdbug.a \
$(top_builddir)/strings/libmystrings.a $(top_builddir)/strings/libmystrings.a
noinst_PROGRAMS = bitmap-t base64-t lf-t my_vsnprintf-t noinst_PROGRAMS = bitmap-t base64-t lf-t my_rdtsc-t my_vsnprintf-t
if NEED_THREAD if NEED_THREAD
# my_atomic-t is used to check thread functions, so it is safe to # my_atomic-t is used to check thread functions, so it is safe to
...@@ -32,5 +32,4 @@ if NEED_THREAD ...@@ -32,5 +32,4 @@ if NEED_THREAD
noinst_PROGRAMS += my_atomic-t noinst_PROGRAMS += my_atomic-t
endif endif
# Don't update the files from bitkeeper EXTRA_DIST = CMakeLists.txt
%::SCCS/s.%
/* Copyright (C) 2008-2009 Sun Microsystems, Inc
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
rdtsc3 -- multi-platform timer code
pgulutzan@mysql.com, 2005-08-29
modified 2008-11-02
When you run rdtsc3, it will print the contents of
"my_timer_info". The display indicates
what timer routine is best for a given platform.
For example, this is the display on production.mysql.com,
a 2.8GHz Xeon with Linux 2.6.17, gcc 3.3.3:
cycles nanoseconds microseconds milliseconds ticks
------------- ------------- ------------- ------------- -------------
1 11 13 18 17
2815019607 1000000000 1000000 1049 102
1 1000 1 1 1
88 4116 3888 4092 2044
The first line shows routines, e.g. 1 = MY_TIMER_ROUTINE_ASM_X86.
The second line shows frequencies, e.g. 2815019607 is nearly 2.8GHz.
The third line shows resolutions, e.g. 1000 = very poor resolution.
The fourth line shows overheads, e.g. ticks takes 2044 cycles.
*/
#include "my_global.h"
#include "my_rdtsc.h"
#include "tap.h"
#define LOOP_COUNT 100
MY_TIMER_INFO myt;
void test_init()
{
my_timer_init(&myt);
diag("----- Routine ---------------");
diag("myt.cycles.routine : %13llu", myt.cycles.routine);
diag("myt.nanoseconds.routine : %13llu", myt.nanoseconds.routine);
diag("myt.microseconds.routine : %13llu", myt.microseconds.routine);
diag("myt.milliseconds.routine : %13llu", myt.milliseconds.routine);
diag("myt.ticks.routine : %13llu", myt.ticks.routine);
diag("----- Frequency -------------");
diag("myt.cycles.frequency : %13llu", myt.cycles.frequency);
diag("myt.nanoseconds.frequency : %13llu", myt.nanoseconds.frequency);
diag("myt.microseconds.frequency : %13llu", myt.microseconds.frequency);
diag("myt.milliseconds.frequency : %13llu", myt.milliseconds.frequency);
diag("myt.ticks.frequency : %13llu", myt.ticks.frequency);
diag("----- Resolution ------------");
diag("myt.cycles.resolution : %13llu", myt.cycles.resolution);
diag("myt.nanoseconds.resolution : %13llu", myt.nanoseconds.resolution);
diag("myt.microseconds.resolution : %13llu", myt.microseconds.resolution);
diag("myt.milliseconds.resolution : %13llu", myt.milliseconds.resolution);
diag("myt.ticks.resolution : %13llu", myt.ticks.resolution);
diag("----- Overhead --------------");
diag("myt.cycles.overhead : %13llu", myt.cycles.overhead);
diag("myt.nanoseconds.overhead : %13llu", myt.nanoseconds.overhead);
diag("myt.microseconds.overhead : %13llu", myt.microseconds.overhead);
diag("myt.milliseconds.overhead : %13llu", myt.milliseconds.overhead);
diag("myt.ticks.overhead : %13llu", myt.ticks.overhead);
ok(1, "my_timer_init() did not crash");
}
void test_cycle()
{
ulonglong t1= my_timer_cycles();
ulonglong t2;
int i;
int backward= 0;
int nonzero= 0;
for (i=0 ; i < LOOP_COUNT ; i++)
{
t2= my_timer_cycles();
if (t1 >= t2)
backward++;
if (t2 != 0)
nonzero++;
t1= t2;
}
/* Expect at most 1 backward, the cycle value can overflow */
ok((backward <= 1), "The cycle timer is strictly increasing");
if (myt.cycles.routine != 0)
ok((nonzero != 0), "The cycle timer is implemented");
else
ok((nonzero == 0), "The cycle timer is not implemented and returns 0");
}
void test_nanosecond()
{
ulonglong t1= my_timer_nanoseconds();
ulonglong t2;
int i;
int backward= 0;
int nonzero= 0;
for (i=0 ; i < LOOP_COUNT ; i++)
{
t2= my_timer_nanoseconds();
if (t1 > t2)
backward++;
if (t2 != 0)
nonzero++;
t1= t2;
}
ok((backward == 0), "The nanosecond timer is increasing");
if (myt.nanoseconds.routine != 0)
ok((nonzero != 0), "The nanosecond timer is implemented");
else
ok((nonzero == 0), "The nanosecond timer is not implemented and returns 0");
}
void test_microsecond()
{
ulonglong t1= my_timer_microseconds();
ulonglong t2;
int i;
int backward= 0;
int nonzero= 0;
for (i=0 ; i < LOOP_COUNT ; i++)
{
t2= my_timer_microseconds();
if (t1 > t2)
backward++;
if (t2 != 0)
nonzero++;
t1= t2;
}
ok((backward == 0), "The microsecond timer is increasing");
if (myt.microseconds.routine != 0)
ok((nonzero != 0), "The microsecond timer is implemented");
else
ok((nonzero == 0), "The microsecond timer is not implemented and returns 0");
}
void test_millisecond()
{
ulonglong t1= my_timer_milliseconds();
ulonglong t2;
int i;
int backward= 0;
int nonzero= 0;
for (i=0 ; i < LOOP_COUNT ; i++)
{
t2= my_timer_milliseconds();
if (t1 > t2)
backward++;
if (t2 != 0)
nonzero++;
t1= t2;
}
ok((backward == 0), "The millisecond timer is increasing");
if (myt.milliseconds.routine != 0)
ok((nonzero != 0), "The millisecond timer is implemented");
else
ok((nonzero == 0), "The millisecond timer is not implemented and returns 0");
}
void test_tick()
{
ulonglong t1= my_timer_ticks();
ulonglong t2;
int i;
int backward= 0;
int nonzero= 0;
for (i=0 ; i < LOOP_COUNT ; i++)
{
t2= my_timer_ticks();
if (t1 > t2)
backward++;
if (t2 != 0)
nonzero++;
t1= t2;
}
ok((backward == 0), "The tick timer is increasing");
if (myt.ticks.routine != 0)
ok((nonzero != 0), "The tick timer is implemented");
else
ok((nonzero == 0), "The tick timer is not implemented and returns 0");
}
int main(int argc __attribute__((unused)),
char ** argv __attribute__((unused)))
{
plan(11);
test_init();
test_cycle();
test_nanosecond();
test_microsecond();
test_millisecond();
test_tick();
return 0;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment