[pypy-commit] stmgc parallel-pulling: some fixes. it seems to improve threadworms by a bit (15%) in the best case.

Raemi noreply at buildbot.pypy.org
Thu Jun 19 15:24:59 CEST 2014


Author: Remi Meier <remi.meier at inf.ethz.ch>
Branch: parallel-pulling
Changeset: r1255:de4815efb600
Date: 2014-06-19 15:25 +0200
http://bitbucket.org/pypy/stmgc/changeset/de4815efb600/

Log:	some fixes. it seems to improve threadworms by a bit (15%) in the
	best case. this may however also get nullified by card-marking

diff --git a/c7/stm/core.c b/c7/stm/core.c
--- a/c7/stm/core.c
+++ b/c7/stm/core.c
@@ -225,7 +225,7 @@
     dprintf(("start_transaction\n"));
 
     s_mutex_unlock();
-    pull_committed_changes();
+    pull_committed_changes(get_priv_segment(STM_SEGMENT->segment_num));
 
     /* Now running the SP_RUNNING start.  We can set our
        'transaction_read_version' after releasing the mutex,
@@ -543,10 +543,6 @@
     if (detect_write_read_conflicts())
         goto restart;
 
-    /* pull changes in case we waited for a transaction to commit
-       in contention management. */
-    pull_committed_changes();
-
     /* cannot abort any more from here */
     dprintf(("commit_transaction\n"));
 
@@ -587,7 +583,6 @@
     /* cannot access STM_SEGMENT or STM_PSEGMENT from here ! */
 
     s_mutex_unlock();
-    pull_committed_changes();
 }
 
 void stm_abort_transaction(void)
@@ -608,24 +603,63 @@
         ({
             /* memcpy in the opposite direction than
                push_modified_to_other_segments() */
-            char *src = REAL_ADDRESS(zero_base, item);
-            char *dst = REAL_ADDRESS(local_base, item);
-            ssize_t size = stmcb_size_rounded_up((struct object_s *)src);
-            memcpy(dst, src, size);
+            char *realobj = REAL_ADDRESS(zero_base, item);
+            ssize_t size = stmcb_size_rounded_up((struct object_s *)realobj);
+
+            /* XXX: copied from sync_object_now */
+            uintptr_t start = (uintptr_t)item;
+            uintptr_t first_page = start / 4096UL;
+
+            if (((struct object_s *)realobj)->stm_flags & GCFLAG_SMALL_UNIFORM) {
+                abort();//XXX WRITE THE FAST CASE
+            }
+            else {
+                uintptr_t end = start + size;
+                uintptr_t last_page = (end - 1) / 4096UL;
+                long myself = segment_num;
+
+                for (; first_page <= last_page; first_page++) {
+                    uintptr_t copy_size;
+                    if (first_page == last_page) {
+                        /* this is the final fragment */
+                        copy_size = end - start;
+                    }
+                    else {
+                        /* this is a non-final fragment, going up to the
+                           page's end */
+                        copy_size = 4096 - (start & 4095);
+                    }
+
+                    /* copy from shared page to private, if needed */
+                    char *dst = REAL_ADDRESS(local_base, start);
+                    char *src = REAL_ADDRESS(zero_base, start);
+                    if (is_private_page(myself, first_page)) {
+                        if (copy_size == 4096)
+                            pagecopy(dst, src);
+                        else
+                            memcpy(dst, src, copy_size);
+                    }
+                    else {
+                        assert(memcmp(dst, src, copy_size) == 0);  /* same page */
+                    }
+
+                    start = (start + 4096) & ~4095;
+                }
+            }
 
             /* all objs in segment 0 should have the WB flag: */
-            assert(((struct object_s *)dst)->stm_flags & GCFLAG_WRITE_BARRIER);
+            assert(((struct object_s *)realobj)->stm_flags & GCFLAG_WRITE_BARRIER);
         }));
     write_fence();
 }
 
-static void pull_committed_changes()
+static void pull_committed_changes(struct stm_priv_segment_info_s *pseg)
 {
-    struct list_s *lst = STM_PSEGMENT->outdated_objects;
+    struct list_s *lst = pseg->outdated_objects;
 
     if (list_count(lst)) {
         dprintf(("pulling %lu objects from shared segment\n", list_count(lst)));
-        copy_objs_from_segment_0(STM_SEGMENT->segment_num, lst);
+        copy_objs_from_segment_0(pseg->pub.segment_num, lst);
         list_clear(lst);
     }
 }
@@ -787,7 +821,7 @@
 {
     s_mutex_lock();
     enter_safe_point_if_requested();
-    pull_committed_changes();   /* XXX: not sure if necessary */
+    pull_committed_changes(get_priv_segment(STM_SEGMENT->segment_num));   /* XXX: not sure if necessary */
 
     if (STM_PSEGMENT->transaction_state == TS_REGULAR) {
         dprintf(("become_inevitable: %s\n", msg));
@@ -804,7 +838,7 @@
     }
 
     s_mutex_unlock();
-    pull_committed_changes();
+    pull_committed_changes(get_priv_segment(STM_SEGMENT->segment_num));
 }
 
 void stm_become_globally_unique_transaction(stm_thread_local_t *tl,
@@ -815,5 +849,5 @@
     s_mutex_lock();
     synchronize_all_threads(STOP_OTHERS_AND_BECOME_GLOBALLY_UNIQUE);
     s_mutex_unlock();
-    pull_committed_changes();
+    pull_committed_changes(get_priv_segment(STM_SEGMENT->segment_num));
 }
diff --git a/c7/stm/core.h b/c7/stm/core.h
--- a/c7/stm/core.h
+++ b/c7/stm/core.h
@@ -262,7 +262,7 @@
 
 static void copy_object_to_shared(object_t *obj, int source_segment_num);
 static void synchronize_object_now(object_t *obj, bool lazy_on_commit);
-static void pull_committed_changes();
+static void pull_committed_changes(struct stm_priv_segment_info_s *pseg);
 
 static inline void acquire_privatization_lock(void)
 {
diff --git a/c7/stm/forksupport.c b/c7/stm/forksupport.c
--- a/c7/stm/forksupport.c
+++ b/c7/stm/forksupport.c
@@ -66,7 +66,7 @@
 
     s_mutex_lock();
     synchronize_all_threads(STOP_OTHERS_UNTIL_MUTEX_UNLOCK);
-    pull_committed_changes();   /* XXX: unclear if necessary */
+    pull_committed_changes(get_priv_segment(STM_SEGMENT->segment_num));   /* XXX: unclear if necessary */
 
     /* Make a new mmap at some other address, but of the same size as
        the standard mmap at stm_object_pages
@@ -81,6 +81,8 @@
     for (i = 1; i <= NB_SEGMENTS; i++) {
         char *src, *dst;
         struct stm_priv_segment_info_s *psrc = get_priv_segment(i);
+        pull_committed_changes(psrc);
+
         dst = big_copy + (((char *)psrc) - stm_object_pages);
         *(struct stm_priv_segment_info_s *)dst = *psrc;
 
diff --git a/c7/stm/gcpage.c b/c7/stm/gcpage.c
--- a/c7/stm/gcpage.c
+++ b/c7/stm/gcpage.c
@@ -153,7 +153,7 @@
     }
 
     s_mutex_unlock();
-    pull_committed_changes();
+    pull_committed_changes(get_priv_segment(STM_SEGMENT->segment_num));
 }
 
 
diff --git a/c7/stm/nursery.c b/c7/stm/nursery.c
--- a/c7/stm/nursery.c
+++ b/c7/stm/nursery.c
@@ -477,6 +477,11 @@
 
     for (i = 1; i <= NB_SEGMENTS; i++) {
         struct stm_priv_segment_info_s *pseg = get_priv_segment(i);
+
+        /* we pull committed changes here so that we are definitely
+           sure all segments are up-to-date */
+        pull_committed_changes(pseg);
+
         if (MINOR_NOTHING_TO_DO(pseg))  /*TS_NONE segments have NOTHING_TO_DO*/
             continue;
 
diff --git a/c7/stm/sync.c b/c7/stm/sync.c
--- a/c7/stm/sync.c
+++ b/c7/stm/sync.c
@@ -255,7 +255,7 @@
     STM_PSEGMENT->safe_point = SP_RUNNING;
 
     stm_safe_point();
-    pull_committed_changes();
+    pull_committed_changes(get_priv_segment(STM_SEGMENT->segment_num));
 }
 #endif
 
@@ -440,5 +440,5 @@
     s_mutex_lock();
     enter_safe_point_if_requested();
     s_mutex_unlock();
-    pull_committed_changes();
+    pull_committed_changes(get_priv_segment(STM_SEGMENT->segment_num));
 }


More information about the pypy-commit mailing list