Author: Remi Meier <[email protected]>
Branch: 
Changeset: r1969:e3071642fd5c
Date: 2015-11-19 16:42 +0100
http://bitbucket.org/pypy/stmgc/changeset/e3071642fd5c/

Log:    free large overflow objs on abort

        Benchmarks show (e.g. lee routing) that the more threads we run, the
        longer major GCs take (bc. there is more memory to look at). E.g.
        Lee on 1 thread spends 12% of its time doing GC; on 4 threads, the
        ratio goes up to 39%.

        This patch tries to lower the work to be done during major GCs by
        freeing overflow objects if the transaction aborted. For now, only
        large ones bc. we miss a smallmalloc_free() function (and it's also
        not clear if freeing small overflow objs should be done early).

        This change improves performance by 5-15% on 4 threads.

diff --git a/c8/stm/core.c b/c8/stm/core.c
--- a/c8/stm/core.c
+++ b/c8/stm/core.c
@@ -1561,6 +1561,14 @@
 
     list_clear(pseg->objects_pointing_to_nursery);
     list_clear(pseg->old_objects_with_cards_set);
+    LIST_FOREACH_R(pseg->large_overflow_objects, uintptr_t /*item*/,
+        {
+            if (is_small_uniform((object_t*)item)) {
+                //_stm_small_free()
+            } else {
+                _stm_large_free(stm_object_pages + item);
+            }
+        });
     list_clear(pseg->large_overflow_objects);
     list_clear(pseg->young_weakrefs);
 #pragma pop_macro("STM_SEGMENT")
diff --git a/c8/stm/detach.c b/c8/stm/detach.c
--- a/c8/stm/detach.c
+++ b/c8/stm/detach.c
@@ -127,6 +127,7 @@
         // XXX: not sure if the next line is a good idea
         tl->last_associated_segment_num = remote_seg_num;
         ensure_gs_register(remote_seg_num);
+        assert(old_tl == STM_SEGMENT->running_thread);
         timing_event(STM_SEGMENT->running_thread, STM_TRANSACTION_REATTACH);
         commit_external_inevitable_transaction();
     }
@@ -186,6 +187,7 @@
     assert(segnum > 0);
 
     ensure_gs_register(segnum);
+    assert(((stm_thread_local_t *)old) == STM_SEGMENT->running_thread);
     timing_event(STM_SEGMENT->running_thread, STM_TRANSACTION_REATTACH);
     commit_external_inevitable_transaction();
     ensure_gs_register(mysegnum);
diff --git a/c8/test/test_basic.py b/c8/test/test_basic.py
--- a/c8/test/test_basic.py
+++ b/c8/test/test_basic.py
@@ -638,6 +638,21 @@
         self.start_transaction()
         assert stm_get_char(lp1) == 'a'
 
+    def test_overflow_freed_on_abort(self):
+        self.start_transaction()
+        big = stm_allocate(GC_LAST_SMALL_SIZE + FAST_ALLOC) # large, outside, 
young obj
+        self.push_root(big)
+        stm_minor_collect() # now 'big' is overflow
+        big = self.pop_root()
+        self.abort_transaction()
+
+        self.start_transaction()
+        big2 = stm_allocate(GC_LAST_SMALL_SIZE + FAST_ALLOC)
+        assert big == big2 # reused slot
+        self.abort_transaction()
+
+
+
     def test_inevitable_transaction_has_priority(self):
         self.start_transaction()
         assert self.is_inevitable() == 0
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to