Author: Carl Friedrich Bolz-Tereick <[email protected]>
Branch: expose-gc-time
Changeset: r95376:24e0860e66ac
Date: 2018-11-28 15:27 +0100
http://bitbucket.org/pypy/pypy/changeset/24e0860e66ac/
Log: switch to use time.time() instead of read_timestamp for the GC time
measuring in hooks and stats
- this gives much more directly useful results
- it's plenty fast enough: on my machine one time.time call takes
~40ns, read_timestamp about ~10ns, while a minor gc step takes
~9000ns
diff --git a/pypy/goal/targetpypystandalone.py
b/pypy/goal/targetpypystandalone.py
--- a/pypy/goal/targetpypystandalone.py
+++ b/pypy/goal/targetpypystandalone.py
@@ -368,7 +368,7 @@
def get_gchooks(self):
from pypy.module.gc.hook import LowLevelGcHooks
if self.space is None:
- raise Exception("get_gchooks must be called afeter
get_entry_point")
+ raise Exception("get_gchooks must be called after get_entry_point")
return self.space.fromcache(LowLevelGcHooks)
def get_entry_point(self, config):
diff --git a/pypy/module/gc/hook.py b/pypy/module/gc/hook.py
--- a/pypy/module/gc/hook.py
+++ b/pypy/module/gc/hook.py
@@ -7,6 +7,8 @@
from pypy.interpreter.typedef import TypeDef, interp_attrproperty,
GetSetProperty
from pypy.interpreter.executioncontext import AsyncAction
+inf = float("inf")
+
class LowLevelGcHooks(GcHooks):
"""
These are the low-level hooks which are called directly from the GC.
@@ -126,9 +128,9 @@
def reset(self):
self.count = 0
- self.duration = r_longlong(0)
- self.duration_min = r_longlong(longlongmax)
- self.duration_max = r_longlong(0)
+ self.duration = 0.0
+ self.duration_min = inf
+ self.duration_max = 0.0
def fix_annotation(self):
# the annotation of the class and its attributes must be completed
@@ -136,9 +138,9 @@
# annotated with the correct types
if NonConstant(False):
self.count = NonConstant(-42)
- self.duration = NonConstant(r_longlong(-42))
- self.duration_min = NonConstant(r_longlong(-42))
- self.duration_max = NonConstant(r_longlong(-42))
+ self.duration = NonConstant(-53.2)
+ self.duration_min = NonConstant(-53.2)
+ self.duration_max = NonConstant(-53.2)
self.total_memory_used = NonConstant(r_uint(42))
self.pinned_objects = NonConstant(-42)
self.fire()
@@ -166,9 +168,9 @@
def reset(self):
self.count = 0
- self.duration = r_longlong(0)
- self.duration_min = r_longlong(longlongmax)
- self.duration_max = r_longlong(0)
+ self.duration = 0.0
+ self.duration_min = inf
+ self.duration_max = 0.0
def fix_annotation(self):
# the annotation of the class and its attributes must be completed
@@ -176,9 +178,9 @@
# annotated with the correct types
if NonConstant(False):
self.count = NonConstant(-42)
- self.duration = NonConstant(r_longlong(-42))
- self.duration_min = NonConstant(r_longlong(-42))
- self.duration_max = NonConstant(r_longlong(-42))
+ self.duration = NonConstant(-53.2)
+ self.duration_min = NonConstant(-53.2)
+ self.duration_max = NonConstant(-53.2)
self.oldstate = NonConstant(-42)
self.newstate = NonConstant(-42)
self.fire()
@@ -276,10 +278,14 @@
# just a shortcut to make the typedefs shorter
-def wrap_many_ints(cls, names):
+def wrap_many(cls, names):
d = {}
for name in names:
- d[name] = interp_attrproperty(name, cls=cls, wrapfn="newint")
+ if "duration" in name:
+ wrapfn = "newfloat"
+ else:
+ wrapfn = "newint"
+ d[name] = interp_attrproperty(name, cls=cls, wrapfn=wrapfn)
return d
@@ -303,7 +309,7 @@
W_GcMinorStats.typedef = TypeDef(
"GcMinorStats",
- **wrap_many_ints(W_GcMinorStats, (
+ **wrap_many(W_GcMinorStats, (
"count",
"duration",
"duration_min",
@@ -319,7 +325,7 @@
STATE_SWEEPING = incminimark.STATE_SWEEPING,
STATE_FINALIZING = incminimark.STATE_FINALIZING,
GC_STATES = tuple(incminimark.GC_STATES),
- **wrap_many_ints(W_GcCollectStepStats, (
+ **wrap_many(W_GcCollectStepStats, (
"count",
"duration",
"duration_min",
@@ -330,7 +336,7 @@
W_GcCollectStats.typedef = TypeDef(
"GcCollectStats",
- **wrap_many_ints(W_GcCollectStats, (
+ **wrap_many(W_GcCollectStats, (
"count",
"num_major_collects",
"arenas_count_before",
diff --git a/pypy/module/gc/test/test_hook.py b/pypy/module/gc/test/test_hook.py
--- a/pypy/module/gc/test/test_hook.py
+++ b/pypy/module/gc/test/test_hook.py
@@ -26,11 +26,11 @@
@unwrap_spec(ObjSpace)
def fire_many(space):
- gchooks.fire_gc_minor(5, 0, 0)
- gchooks.fire_gc_minor(7, 0, 0)
- gchooks.fire_gc_collect_step(5, 0, 0)
- gchooks.fire_gc_collect_step(15, 0, 0)
- gchooks.fire_gc_collect_step(22, 0, 0)
+ gchooks.fire_gc_minor(5.0, 0, 0)
+ gchooks.fire_gc_minor(7.0, 0, 0)
+ gchooks.fire_gc_collect_step(5.0, 0, 0)
+ gchooks.fire_gc_collect_step(15.0, 0, 0)
+ gchooks.fire_gc_collect_step(22.0, 0, 0)
gchooks.fire_gc_collect(1, 2, 3, 4, 5, 6)
cls.w_fire_gc_minor = space.wrap(interp2app(fire_gc_minor))
diff --git a/rpython/memory/gc/incminimark.py b/rpython/memory/gc/incminimark.py
--- a/rpython/memory/gc/incminimark.py
+++ b/rpython/memory/gc/incminimark.py
@@ -74,7 +74,6 @@
from rpython.rlib.debug import ll_assert, debug_print, debug_start, debug_stop
from rpython.rlib.objectmodel import specialize
from rpython.rlib import rgc
-from rpython.rlib.rtimer import read_timestamp
from rpython.memory.gc.minimarkpage import out_of_memory
#
@@ -193,15 +192,6 @@
# ____________________________________________________________
-def count_gc_time(meth):
- def timing_meth(self, *args):
- t1 = time.time()
- res = meth(self, *args)
- t2 = time.time()
- self.total_gc_time += t2 - t1
- return res
- timing_meth.func_name = meth.func_name + "_timing"
- return timing_meth
class IncrementalMiniMarkGC(MovingGCBase):
@@ -1653,12 +1643,11 @@
# ----------
# Nursery collection
- @count_gc_time
def _minor_collection(self):
"""Perform a minor collection: find the objects from the nursery
that remain alive and move them out."""
#
- start = read_timestamp()
+ start = time.time()
debug_start("gc-minor")
#
# All nursery barriers are invalid from this point on. They
@@ -1857,7 +1846,8 @@
self.root_walker.finished_minor_collection()
#
debug_stop("gc-minor")
- duration = read_timestamp() - start
+ duration = time.time() - start
+ self.total_gc_time += duration
self.hooks.fire_gc_minor(
duration=duration,
total_memory_used=total_memory_used,
@@ -2262,9 +2252,8 @@
# Note - minor collections seem fast enough so that one
# is done before every major collection step
- @count_gc_time
def major_collection_step(self, reserving_size=0):
- start = read_timestamp()
+ start = time.time()
debug_start("gc-collect-step")
oldstate = self.gc_state
debug_print("starting gc state: ", GC_STATES[self.gc_state])
@@ -2508,7 +2497,8 @@
debug_print("stopping, now in gc state: ", GC_STATES[self.gc_state])
debug_stop("gc-collect-step")
- duration = read_timestamp() - start
+ duration = time.time() - start
+ self.total_gc_time += duration
self.hooks.fire_gc_collect_step(
duration=duration,
oldstate=oldstate,
@@ -3110,7 +3100,6 @@
return llmemory.NULL
- @count_gc_time
def rrc_invoke_callback(self):
if self.rrc_enabled and self.rrc_dealloc_pending.non_empty():
self.rrc_dealloc_trigger_callback()
diff --git a/rpython/memory/gc/test/test_hook.py
b/rpython/memory/gc/test/test_hook.py
--- a/rpython/memory/gc/test/test_hook.py
+++ b/rpython/memory/gc/test/test_hook.py
@@ -70,7 +70,7 @@
assert self.gc.hooks.minors == [
{'total_memory_used': 0, 'pinned_objects': 0}
]
- assert self.gc.hooks.durations[0] > 0
+ assert self.gc.hooks.durations[0] > 0.
self.gc.hooks.reset()
#
# these objects survive, so the total_memory_used is > 0
@@ -103,7 +103,7 @@
]
assert len(self.gc.hooks.durations) == 4 # 4 steps
for d in self.gc.hooks.durations:
- assert d > 0
+ assert d > 0.0
self.gc.hooks.reset()
#
self.stackroots.append(self.malloc(S))
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit