[pypy-commit] stmgc c8-adaptive-trx-length-per-thread: Implement a per thread adaptive single thread mode

tobweber pypy.commits at gmail.com
Sun May 7 14:16:57 EDT 2017


Author: Tobias Weber <tobias_weber89 at gmx.de>
Branch: c8-adaptive-trx-length-per-thread
Changeset: r2058:cbb625d908bf
Date: 2017-05-07 20:16 +0200
http://bitbucket.org/pypy/stmgc/changeset/cbb625d908bf/

Log:	Implement a per thread adaptive single thread mode

diff --git a/c8/stm/core.c b/c8/stm/core.c
--- a/c8/stm/core.c
+++ b/c8/stm/core.c
@@ -1167,9 +1167,8 @@
     }
     if (repeat_count == 0) {  /* else, 'nursery_mark' was already set
                                  in abort_data_structures_from_segment_num() */
-        stm_update_transaction_length();
         STM_SEGMENT->nursery_mark = ((stm_char *)_stm_nursery_start +
-                                     stm_fill_mark_nursery_bytes);
+                                        stm_get_transaction_length(tl));
     }
     return repeat_count;
 }
diff --git a/c8/stm/nursery.c b/c8/stm/nursery.c
--- a/c8/stm/nursery.c
+++ b/c8/stm/nursery.c
@@ -23,61 +23,42 @@
 uintptr_t stm_fill_mark_nursery_bytes = DEFAULT_FILL_MARK_NURSERY_BYTES;
 // uintptr_t stm_fill_mark_nursery_bytes = LARGE_FILL_MARK_NURSERY_BYTES;
 
-#define STM_MIN_RELATIVE_TRANSACTION_LENGTH (0.000001f)
-static float stm_relative_transaction_length = STM_MIN_RELATIVE_TRANSACTION_LENGTH;
-static int stm_increase_transaction_length_backoff = 0;
+#define STM_MIN_RELATIVE_TRANSACTION_LENGTH (0.00000001f)
 
-static void reset_or_decrease_backoff(bool reset) {
-    int actual_backoff = stm_increase_transaction_length_backoff;
-    int expected_backoff;
-    int value = 5;
-    do {
-        expected_backoff = actual_backoff;
-        if (!reset) {
-            value = actual_backoff - 1;
-        }
-        actual_backoff = __atomic_exchange_n(
-            &stm_increase_transaction_length_backoff, value, __ATOMIC_RELAXED);
-    } while (expected_backoff != actual_backoff && (reset || actual_backoff > 0));
-}
-
-static float get_new_transaction_length(bool aborts, float previous) {
-    const int multiplier = 2;
+static float get_new_transaction_length(stm_thread_local_t *tl, bool aborts) {
+    const int multiplier = 100;
+    float previous = tl->relative_transaction_length;
     float new = previous;
     if (aborts) {
-        reset_or_decrease_backoff(true); // reset backoff
+        tl->transaction_length_backoff = 3;
         if (previous > STM_MIN_RELATIVE_TRANSACTION_LENGTH) {
             new = previous / multiplier;
         } else {
             new = 0;
         }
-    } else if (stm_increase_transaction_length_backoff == 0) {
+    } else if (tl->transaction_length_backoff == 0) {
         if (previous - (STM_MIN_RELATIVE_TRANSACTION_LENGTH * 0.1) < 0) {
             new = STM_MIN_RELATIVE_TRANSACTION_LENGTH;
         } else if (previous < 1) {
             new = previous * multiplier;
         }
     } else { // not abort and backoff != 0
-        reset_or_decrease_backoff(false); // decrease backoff by one
+        tl->transaction_length_backoff -= 1;
     }
     return new;
 }
 
 static void stm_transaction_length_handle_validation(stm_thread_local_t *tl, bool aborts) {
-    float actual = stm_relative_transaction_length;
-    float expected;
-    do {
-        expected = actual;
-        float new = get_new_transaction_length(aborts, actual);
-        __atomic_exchange(
-            &stm_relative_transaction_length, &new, &actual, __ATOMIC_RELAXED);
-    } while (fabs(actual - expected) > (STM_MIN_RELATIVE_TRANSACTION_LENGTH * 0.1));
+    if (!tl->initialized) {
+        tl->relative_transaction_length = STM_MIN_RELATIVE_TRANSACTION_LENGTH;
+        tl->initialized = true;
+    }
+    float new = get_new_transaction_length(tl, aborts);
+    tl->relative_transaction_length = new;
 }
 
-static void stm_update_transaction_length(void) {
-    float relative_additional_length = stm_relative_transaction_length;
-    stm_fill_mark_nursery_bytes = DEFAULT_FILL_MARK_NURSERY_BYTES +
-        (uintptr_t)(LARGE_FILL_MARK_NURSERY_BYTES * relative_additional_length);
+static uintptr_t stm_get_transaction_length(stm_thread_local_t *tl) {
+    float relative_additional_length = tl->relative_transaction_length;
     if (timing_enabled()) {
         struct timespec relative_length = {
             .tv_sec = (int)relative_additional_length,
@@ -89,6 +70,8 @@
             STM_SINGLE_THREAD_MODE_ADAPTIVE,
             &stm_duration_payload);
     }
+    return DEFAULT_FILL_MARK_NURSERY_BYTES +
+        (uintptr_t)(LARGE_FILL_MARK_NURSERY_BYTES * relative_additional_length);
 }
 
 
diff --git a/c8/stm/nursery.h b/c8/stm/nursery.h
--- a/c8/stm/nursery.h
+++ b/c8/stm/nursery.h
@@ -60,6 +60,6 @@
 static uint32_t stm_global_conflicts;
 
 static void stm_transaction_length_handle_validation(stm_thread_local_t *tl, bool aborts);
-static void stm_update_transaction_length(void);
+static uintptr_t stm_get_transaction_length(stm_thread_local_t *tl);
 
 #endif
diff --git a/c8/stmgc.h b/c8/stmgc.h
--- a/c8/stmgc.h
+++ b/c8/stmgc.h
@@ -9,6 +9,7 @@
 
 #include <stddef.h>
 #include <stdint.h>
+#include <stdbool.h>
 #include <assert.h>
 #include <limits.h>
 #include <unistd.h>
@@ -88,6 +89,10 @@
     struct stm_thread_local_s *prev, *next;
     intptr_t self_or_0_if_atomic;
     void *creating_pthread[2];
+    /* adaptive single thread mode */
+    float relative_transaction_length;
+    int transaction_length_backoff;
+    bool initialized;
 } stm_thread_local_t;
 
 


More information about the pypy-commit mailing list