From c44ba01de7f050f126a8a7b2ddeb6286237bb384 Mon Sep 17 00:00:00 2001 From: AndreyChurbanov Date: Wed, 18 May 2022 10:01:18 -0500 Subject: [PATCH] [OpenMP] libomp: honor passive wait policy requested with tasking Currently the library ignores requested wait policy in the presence of tasking. Threads always actively spin. The patch fixes this problem making the wait policy passive if this explicitly requested by user. Differential Revision: https://reviews.llvm.org/D123044 --- openmp/runtime/src/kmp.h | 1 + openmp/runtime/src/kmp_global.cpp | 1 + openmp/runtime/src/kmp_settings.cpp | 1 + openmp/runtime/src/kmp_tasking.cpp | 26 +++++++++++++++++++++++++- openmp/runtime/src/kmp_wait_release.h | 3 ++- 5 files changed, 30 insertions(+), 2 deletions(-) diff --git a/openmp/runtime/src/kmp.h b/openmp/runtime/src/kmp.h index fe4d551..41d3b64 100644 --- a/openmp/runtime/src/kmp.h +++ b/openmp/runtime/src/kmp.h @@ -3160,6 +3160,7 @@ extern int __kmp_tp_cached; /* whether threadprivate cache has been created (__kmpc_threadprivate_cached()) */ extern int __kmp_dflt_blocktime; /* number of milliseconds to wait before blocking (env setting) */ +extern bool __kmp_wpolicy_passive; /* explicitly set passive wait policy */ #if KMP_USE_MONITOR extern int __kmp_monitor_wakeups; /* number of times monitor wakes up per second */ diff --git a/openmp/runtime/src/kmp_global.cpp b/openmp/runtime/src/kmp_global.cpp index 2a0378d..a82c3da 100644 --- a/openmp/runtime/src/kmp_global.cpp +++ b/openmp/runtime/src/kmp_global.cpp @@ -154,6 +154,7 @@ int __kmp_hier_threads_per[kmp_hier_layer_e::LAYER_LAST + 1]; kmp_hier_sched_env_t __kmp_hier_scheds = {0, 0, NULL, NULL, NULL}; #endif int __kmp_dflt_blocktime = KMP_DEFAULT_BLOCKTIME; +bool __kmp_wpolicy_passive = false; #if KMP_USE_MONITOR int __kmp_monitor_wakeups = KMP_MIN_MONITOR_WAKEUPS; int __kmp_bt_intervals = KMP_INTERVALS_FROM_BLOCKTIME(KMP_DEFAULT_BLOCKTIME, diff --git a/openmp/runtime/src/kmp_settings.cpp b/openmp/runtime/src/kmp_settings.cpp index 481f605..c003294 100644 --- a/openmp/runtime/src/kmp_settings.cpp +++ b/openmp/runtime/src/kmp_settings.cpp @@ -812,6 +812,7 @@ static void __kmp_stg_parse_wait_policy(char const *name, char const *value, } } else if (__kmp_str_match("PASSIVE", 1, value)) { __kmp_library = library_throughput; + __kmp_wpolicy_passive = true; /* allow sleep while active tasking */ if (blocktime_str == NULL) { // KMP_BLOCKTIME not specified, so set default to 0. __kmp_dflt_blocktime = 0; diff --git a/openmp/runtime/src/kmp_tasking.cpp b/openmp/runtime/src/kmp_tasking.cpp index 159c50e..1622c6a 100644 --- a/openmp/runtime/src/kmp_tasking.cpp +++ b/openmp/runtime/src/kmp_tasking.cpp @@ -1909,8 +1909,21 @@ kmp_int32 __kmp_omp_task(kmp_int32 gtid, kmp_task_t *new_task, if (serialize_immediate) new_taskdata->td_flags.task_serial = 1; __kmp_invoke_task(gtid, new_task, current_task); + } else if (__kmp_dflt_blocktime != KMP_MAX_BLOCKTIME && + __kmp_wpolicy_passive) { + kmp_info_t *this_thr = __kmp_threads[gtid]; + kmp_team_t *team = this_thr->th.th_team; + kmp_int32 nthreads = this_thr->th.th_team_nproc; + for (int i = 0; i < nthreads; ++i) { + kmp_info_t *thread = team->t.t_threads[i]; + if (thread == this_thr) + continue; + if (thread->th.th_sleep_loc != NULL) { + __kmp_null_resume_wrapper(thread); + break; // awake one thread at a time + } + } } - return TASK_CURRENT_NOT_QUEUED; } @@ -4282,6 +4295,17 @@ void __kmpc_give_task(kmp_task_t *ptask, kmp_int32 start = 0) { pass = pass << 1; } while (!__kmp_give_task(thread, k, ptask, pass)); + + if (__kmp_dflt_blocktime != KMP_MAX_BLOCKTIME && __kmp_wpolicy_passive) { + // awake at least one thread to execute given task + for (int i = 0; i < nthreads; ++i) { + thread = team->t.t_threads[i]; + if (thread->th.th_sleep_loc != NULL) { + __kmp_null_resume_wrapper(thread); + break; + } + } + } } /*! diff --git a/openmp/runtime/src/kmp_wait_release.h b/openmp/runtime/src/kmp_wait_release.h index 962f657..3fcae56 100644 --- a/openmp/runtime/src/kmp_wait_release.h +++ b/openmp/runtime/src/kmp_wait_release.h @@ -609,7 +609,8 @@ final_spin=FALSE) continue; // Don't suspend if there is a likelihood of new tasks being spawned. - if ((task_team != NULL) && TCR_4(task_team->tt.tt_found_tasks)) + if (task_team != NULL && TCR_4(task_team->tt.tt_found_tasks) && + !__kmp_wpolicy_passive) continue; #if KMP_USE_MONITOR -- 2.7.4