diff options
author | Jonathan Peyton <jonathan.l.peyton@intel.com> | 2019-02-11 21:04:23 +0000 |
---|---|---|
committer | Jonathan Peyton <jonathan.l.peyton@intel.com> | 2019-02-11 21:04:23 +0000 |
commit | 65ebfeecf88e68f34c8fc1604da042ffad5ebd8b (patch) | |
tree | 563c34e4b57e3e0702871829062d2b89c73e27c0 /openmp/runtime/src/kmp.h | |
parent | 24e0af69066e1d5ab0a6b4d75ff81d57f5b02f18 (diff) | |
download | bcm5719-llvm-65ebfeecf88e68f34c8fc1604da042ffad5ebd8b.tar.gz bcm5719-llvm-65ebfeecf88e68f34c8fc1604da042ffad5ebd8b.zip |
[OpenMP] Fix thread_limits to work properly for teams construct
The thread-limit-var and omp_get_thread_limit API was not perfectly handled for
teams construct. Now, when modified by thread_limit clause, omp_get_thread_limit
reports the correct value. In addition, the value is restored when leaving the
teams construct to what it was in the encountering context.
This is done partly by creating the notion of a Contention Group root (CG root)
that keeps track of the thread at the root of each separate CG, the
thread-limit-var associated with the CG, and associated counter of active
threads within the contention group.
thread-limits are passed from master to worker threads via an entry in the ICV
data structure. When a "contention group switch" occurs, a new CG root record is
made and passed from master to worker. A thread could potentially have several
CG root records if it encounters multiple nested teams constructs (but at the
moment the spec doesn't allow for nested teams, so the most one could have
currently is 2). The master of the teams masters gets the thread-limit clause
value stored to its local ICV structure, and the other teams masters copy it
from the master. The thread-limit is set from that ICV copy and restored to the
ICV copy when entering and leaving the teams construct.
This change also fixes a bug when the top-level teams construct team gets
reused, and OMP_DYNAMIC was true, which can cause the expected size of this team
to be smaller than what was actually allocated. The fix updates the size of the
team after its threads were reserved.
Patch by Terry Wilmarth
Differential Revision: https://reviews.llvm.org/D56804
llvm-svn: 353747
Diffstat (limited to 'openmp/runtime/src/kmp.h')
-rw-r--r-- | openmp/runtime/src/kmp.h | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/openmp/runtime/src/kmp.h b/openmp/runtime/src/kmp.h index 5795a32da8c..5ad992aa19b 100644 --- a/openmp/runtime/src/kmp.h +++ b/openmp/runtime/src/kmp.h @@ -1847,6 +1847,7 @@ typedef struct kmp_internal_control { #endif int nproc; /* internal control for #threads for next parallel region (per thread) */ + int thread_limit; /* internal control for thread-limit-var */ int max_active_levels; /* internal control for max_active_levels */ kmp_r_sched_t sched; /* internal control for runtime schedule {sched,chunk} pair */ @@ -2077,6 +2078,9 @@ typedef struct kmp_local { #define set__nproc(xthread, xval) \ (((xthread)->th.th_current_task->td_icvs.nproc) = (xval)) +#define set__thread_limit(xthread, xval) \ + (((xthread)->th.th_current_task->td_icvs.thread_limit) = (xval)) + #define set__max_active_levels(xthread, xval) \ (((xthread)->th.th_current_task->td_icvs.max_active_levels) = (xval)) @@ -2458,6 +2462,26 @@ typedef struct kmp_teams_size { } kmp_teams_size_t; #endif +// This struct stores a thread that acts as a "root" for a contention +// group. Contention groups are rooted at kmp_root threads, but also at +// each master thread of each team created in the teams construct. +// This struct therefore also stores a thread_limit associated with +// that contention group, and a counter to track the number of threads +// active in that contention group. Each thread has a list of these: CG +// root threads have an entry in their list in which cg_root refers to +// the thread itself, whereas other workers in the CG will have a +// single entry where cg_root is same as the entry containing their CG +// root. When a thread encounters a teams construct, it will add a new +// entry to the front of its list, because it now roots a new CG. +typedef struct kmp_cg_root { + kmp_info_p *cg_root; // "root" thread for a contention group + // The CG root's limit comes from OMP_THREAD_LIMIT for root threads, or + // thread_limit clause for teams masters + kmp_int32 cg_thread_limit; + kmp_int32 cg_nthreads; // Count of active threads in CG rooted at cg_root + struct kmp_cg_root *up; // pointer to higher level CG root in list +} kmp_cg_root_t; + // OpenMP thread data structures typedef struct KMP_ALIGN_CACHE kmp_base_info { @@ -2605,6 +2629,7 @@ typedef struct KMP_ALIGN_CACHE kmp_base_info { #if KMP_OS_UNIX std::atomic<bool> th_blocking; #endif + kmp_cg_root_t *th_cg_roots; // list of cg_roots associated with this thread } kmp_base_info_t; typedef union KMP_ALIGN_CACHE kmp_info { @@ -2796,7 +2821,6 @@ typedef struct kmp_base_root { kmp_lock_t r_begin_lock; volatile int r_begin; int r_blocktime; /* blocktime for this root and descendants */ - int r_cg_nthreads; // count of active threads in a contention group } kmp_base_root_t; typedef union KMP_ALIGN_CACHE kmp_root { |