[pypy-svn] pypy jit-lsprofile: (alex, mitsuhiko, fijal): Move timer function to rlib and use assembler.

alex_gaynor commits-noreply at bitbucket.org
Sun Mar 13 19:30:20 CET 2011


Author: Alex Gaynor <alex.gaynor at gmail.com>
Branch: jit-lsprofile
Changeset: r42563:7cd4d3e4d745
Date: 2011-03-13 14:30 -0400
http://bitbucket.org/pypy/pypy/changeset/7cd4d3e4d745/

Log:	(alex, mitsuhiko, fijal): Move timer function to rlib and use
	assembler.

diff --git a/pypy/module/_lsprof/interp_lsprof.py b/pypy/module/_lsprof/interp_lsprof.py
--- a/pypy/module/_lsprof/interp_lsprof.py
+++ b/pypy/module/_lsprof/interp_lsprof.py
@@ -8,21 +8,11 @@
                                       interp_attrproperty)
 from pypy.rlib import jit
 from pypy.rpython.lltypesystem import rffi
-from pypy.tool.autopath import pypydir
 
 import time, sys
 
 # timer
 
-eci = rffi.ExternalCompilationInfo(
-    include_dirs = [str(py.path.local(pypydir).join('translator', 'c'))],
-    includes=["src/timer.h"],
-    separate_module_sources = [' '],
-    )
-read_timestamp_double = rffi.llexternal(
-    'pypy_read_timestamp_double', [], rffi.DOUBLE,
-    compilation_info=eci, _nowrapper=True)
-
 class W_StatsEntry(Wrappable):
     def __init__(self, space, frame, callcount, reccallcount, tt, it,
                  w_sublist):

diff --git a/pypy/translator/c/src/timer.h b/pypy/translator/c/src/timer.h
--- a/pypy/translator/c/src/timer.h
+++ b/pypy/translator/c/src/timer.h
@@ -10,37 +10,26 @@
 #ifndef PYPY_NOT_MAIN_FILE
 /* implementations */
 
-#  ifdef _WIN32
-    double pypy_read_timestamp_double(void) {
-        static double pypy_timer_scale = 0.0;
-        long long timestamp;
-        long long scale;
-        QueryPerformanceCounter((LARGE_INTEGER*)&(timestamp));
-        if (pypy_timer_scale == 0.0) {
-          QueryPerformanceFrequency((LARGE_INTEGER*)&(scale));
-          pypy_timer_scale = 1.0 / (double)scale;
-        }
-        return ((double)timestamp) * pypy_timer_scale;
-    }
+#ifdef _WIN32
+long long pypy_read_timestamp(void) {
+    long long timestamp;
+    long long scale;
+    QueryPerformanceCounter((LARGE_INTEGER*)&(timestamp));
+    return timestamp;
+}
 
-#  else
-#    include <time.h>
-#    include <sys/time.h>
+#else
 
-     double pypy_read_timestamp_double(void)
-     {
-#    ifdef CLOCK_THREAD_CPUTIME_ID
-       struct timespec tspec;
-       clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tspec);
-       return ((double)tspec.tv_sec) + ((double)tspec.tv_nsec) / 1e9;
-#    else
-       /* argh, we don't seem to have clock_gettime().  Bad OS. */
-       struct timeval tv;
-       gettimeofday(&tv, NULL);
-       return ((double)tv.tv_sec) + ((double)tv.tv_usec) / 1e6;
-#    endif
-     }
+#include "inttypes.h"
 
-# endif
+long long pypy_read_timestamp(void) {
+    uint32_t low, high;
+    __asm__ __volatile__ (
+        "rdtsc" : "=a" (low), "=d" (high)
+    );
+    return ((long long)high << 32) + low;
+}
+
 #endif
 #endif
+#endif

diff --git a/pypy/rlib/rtimer.py b/pypy/rlib/rtimer.py
new file mode 100644
--- /dev/null
+++ b/pypy/rlib/rtimer.py
@@ -0,0 +1,21 @@
+import time
+
+import py
+
+from pypy.rlib.rarithmetic import r_longlong
+from pypy.rpython.lltypesystem import rffi
+from pypy.tool.autopath import pypydir
+
+
+eci = rffi.ExternalCompilationInfo(
+    include_dirs = [str(py.path.local(pypydir).join('translator', 'c'))],
+    includes=["src/timer.h"],
+    separate_module_sources = [' '],
+)
+c_read_timestamp = rffi.llexternal(
+    'pypy_read_timestamp', [], rffi.LONGLONG,
+    compilation_info=eci, _nowrapper=True
+)
+
+def read_timestamp():
+    return c_read_timestamp()
\ No newline at end of file

diff --git a/pypy/module/_lsprof/test/test_cprofile.py b/pypy/module/_lsprof/test/test_cprofile.py
--- a/pypy/module/_lsprof/test/test_cprofile.py
+++ b/pypy/module/_lsprof/test/test_cprofile.py
@@ -1,16 +1,6 @@
 import py
 from pypy.conftest import gettestobjspace, option
 
-def test_timer():
-    from pypy.module._lsprof.interp_lsprof import read_timestamp_double
-    import time
-    t1 = read_timestamp_double()
-    start = time.time()
-    while time.time() - start < 1.0:
-        pass     # busy wait
-    t2 = read_timestamp_double()
-    assert 0.9 < t2 - t1 < 1.9
-
 class AppTestCProfile(object):
     keywords = {}
 

diff --git a/pypy/rlib/test/test_rtimer.py b/pypy/rlib/test/test_rtimer.py
new file mode 100644
--- /dev/null
+++ b/pypy/rlib/test/test_rtimer.py
@@ -0,0 +1,14 @@
+import time
+
+from pypy.rlib.rtimer import read_timestamp
+
+
+def test_timer():
+    t1 = read_timestamp()
+    start = time.time()
+    while time.time() - start < 1.0:
+        # busy wait
+        pass
+    t2 = read_timestamp()
+    # We're counting ticks, verify they look correct
+    assert t2 - t1 > 1000


More information about the Pypy-commit mailing list