[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