Author: Carl Friedrich Bolz-Tereick <cfb...@gmx.de> 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 pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit