Author: Tobias Weber <tobias_webe...@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; _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit