diff options
author | Jonathan Peyton <jonathan.l.peyton@intel.com> | 2016-11-14 21:08:35 +0000 |
---|---|---|
committer | Jonathan Peyton <jonathan.l.peyton@intel.com> | 2016-11-14 21:08:35 +0000 |
commit | d4da538d3c5ec0ee9d22d417fff9ec3721c0fa32 (patch) | |
tree | 7996f994e9cdafa3340acb16d4ac5a3ec9607074 /runtime/src/kmp_affinity.cpp | |
parent | 76755788c3fe74c8d5382133fb32d5f917ae2ce3 (diff) |
Introduce dynamic affinity dispatch capabilities
This set of changes enables the affinity interface (Either the preexisting
native operating system or HWLOC) to be dynamically set at runtime
initialization. The point of this change is that we were seeing performance
degradations when using HWLOC. This allows the user to use the old affinity
mechanisms which on large machines (>64 cores) makes a large difference in
initialization time.
These changes mostly move affinity code under a small class hierarchy:
KMPAffinity
class Mask {}
KMPNativeAffinity : public KMPAffinity
class Mask : public KMPAffinity::Mask
KMPHwlocAffinity
class Mask : public KMPAffinity::Mask
Since all interface functions (for both affinity and the mask implementation)
are virtual, the implementation can be chosen at runtime initialization.
Differential Revision: https://reviews.llvm.org/D26356
git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@286890 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'runtime/src/kmp_affinity.cpp')
-rw-r--r-- | runtime/src/kmp_affinity.cpp | 98 |
1 files changed, 42 insertions, 56 deletions
diff --git a/runtime/src/kmp_affinity.cpp b/runtime/src/kmp_affinity.cpp index 93299b5..f09c3cd 100644 --- a/runtime/src/kmp_affinity.cpp +++ b/runtime/src/kmp_affinity.cpp @@ -47,53 +47,42 @@ void __kmp_get_hierarchy(kmp_uint32 nproc, kmp_bstate_t *thr_bar) { #if KMP_AFFINITY_SUPPORTED -// -// Print the affinity mask to the character array in a pretty format. -// +bool KMPAffinity::picked_api = false; + +void* KMPAffinity::Mask::operator new(size_t n) { return __kmp_allocate(n); } +void* KMPAffinity::Mask::operator new[](size_t n) { return __kmp_allocate(n); } +void KMPAffinity::Mask::operator delete(void* p) { __kmp_free(p); } +void KMPAffinity::Mask::operator delete[](void* p) { __kmp_free(p); } +void* KMPAffinity::operator new(size_t n) { return __kmp_allocate(n); } +void KMPAffinity::operator delete(void* p) { __kmp_free(p); } + +void KMPAffinity::pick_api() { + KMPAffinity* affinity_dispatch; + if (picked_api) + return; #if KMP_USE_HWLOC -char * -__kmp_affinity_print_mask(char *buf, int buf_len, kmp_affin_mask_t *mask) -{ - int num_chars_to_write, num_chars_written; - char* scan; - KMP_ASSERT(buf_len >= 40); + if (__kmp_affinity_top_method == affinity_top_method_hwloc) { + affinity_dispatch = new KMPHwlocAffinity(); + } else +#endif + { + affinity_dispatch = new KMPNativeAffinity(); + } + __kmp_affinity_dispatch = affinity_dispatch; + picked_api = true; +} - // bufsize of 0 just retrieves the needed buffer size. - num_chars_to_write = hwloc_bitmap_list_snprintf(buf, 0, (hwloc_bitmap_t)mask); - - // need '{', "xxxxxxxx...xx", '}', '\0' = num_chars_to_write + 3 bytes - // * num_chars_to_write returned by hwloc_bitmap_list_snprintf does not - // take into account the '\0' character. - if(hwloc_bitmap_iszero((hwloc_bitmap_t)mask)) { - KMP_SNPRINTF(buf, buf_len, "{<empty>}"); - } else if(num_chars_to_write < buf_len - 3) { - // no problem fitting the mask into buf_len number of characters - buf[0] = '{'; - // use buf_len-3 because we have the three characters: '{' '}' '\0' to add to the buffer - num_chars_written = hwloc_bitmap_list_snprintf(buf+1, buf_len-3, (hwloc_bitmap_t)mask); - buf[num_chars_written+1] = '}'; - buf[num_chars_written+2] = '\0'; - } else { - // Need to truncate the affinity mask string and add ellipsis. - // To do this, we first write out the '{' + str(mask) - buf[0] = '{'; - hwloc_bitmap_list_snprintf(buf+1, buf_len-1, (hwloc_bitmap_t)mask); - // then, what we do here is go to the 7th to last character, then go backwards until we are NOT - // on a digit then write "...}\0". This way it is a clean ellipsis addition and we don't - // overwrite part of an affinity number. i.e., we avoid something like { 45, 67, 8...} and get - // { 45, 67,...} instead. - scan = buf + buf_len - 7; - while(*scan >= '0' && *scan <= '9' && scan >= buf) - scan--; - *(scan+1) = '.'; - *(scan+2) = '.'; - *(scan+3) = '.'; - *(scan+4) = '}'; - *(scan+5) = '\0'; +void KMPAffinity::destroy_api() { + if (__kmp_affinity_dispatch != NULL) { + delete __kmp_affinity_dispatch; + __kmp_affinity_dispatch = NULL; + picked_api = false; } - return buf; } -#else + +// +// Print the affinity mask to the character array in a pretty format. +// char * __kmp_affinity_print_mask(char *buf, int buf_len, kmp_affin_mask_t *mask) { @@ -105,12 +94,8 @@ __kmp_affinity_print_mask(char *buf, int buf_len, kmp_affin_mask_t *mask) // Find first element / check for empty set. // size_t i; - for (i = 0; i < KMP_CPU_SETSIZE; i++) { - if (KMP_CPU_ISSET(i, mask)) { - break; - } - } - if (i == KMP_CPU_SETSIZE) { + i = mask->begin(); + if (i == mask->end()) { KMP_SNPRINTF(scan, end-scan+1, "{<empty>}"); while (*scan != '\0') scan++; KMP_ASSERT(scan <= end); @@ -120,7 +105,7 @@ __kmp_affinity_print_mask(char *buf, int buf_len, kmp_affin_mask_t *mask) KMP_SNPRINTF(scan, end-scan+1, "{%ld", (long)i); while (*scan != '\0') scan++; i++; - for (; i < KMP_CPU_SETSIZE; i++) { + for (; i != mask->end(); i = mask->next(i)) { if (! KMP_CPU_ISSET(i, mask)) { continue; } @@ -137,7 +122,7 @@ __kmp_affinity_print_mask(char *buf, int buf_len, kmp_affin_mask_t *mask) KMP_SNPRINTF(scan, end-scan+1, ",%-ld", (long)i); while (*scan != '\0') scan++; } - if (i < KMP_CPU_SETSIZE) { + if (i != mask->end()) { KMP_SNPRINTF(scan, end-scan+1, ",..."); while (*scan != '\0') scan++; } @@ -146,7 +131,6 @@ __kmp_affinity_print_mask(char *buf, int buf_len, kmp_affin_mask_t *mask) KMP_ASSERT(scan <= end); return buf; } -#endif // KMP_USE_HWLOC void @@ -677,7 +661,7 @@ __kmp_affinity_create_flat_map(AddrUnsPair **address2os, __kmp_pu_os_idx = (int*)__kmp_allocate(sizeof(int) * __kmp_avail_proc); if (__kmp_affinity_type == affinity_none) { int avail_ct = 0; - unsigned int i; + int i; KMP_CPU_SET_ITERATE(i, __kmp_affin_fullMask) { if (! KMP_CPU_ISSET(i, __kmp_affin_fullMask)) continue; @@ -1031,7 +1015,7 @@ __kmp_affinity_create_apicid_map(AddrUnsPair **address2os, } KMP_DEBUG_ASSERT((int)nApics < __kmp_avail_proc); - __kmp_affinity_bind_thread(i); + __kmp_affinity_dispatch->bind_thread(i); threadInfo[nApics].osId = i; // @@ -1547,7 +1531,7 @@ __kmp_affinity_create_x2apicid_map(AddrUnsPair **address2os, } KMP_DEBUG_ASSERT(nApics < __kmp_avail_proc); - __kmp_affinity_bind_thread(proc); + __kmp_affinity_dispatch->bind_thread(proc); // // Extrach the labels for each level in the machine topology map @@ -3705,7 +3689,7 @@ __kmp_aux_affinity_initialize(void) const char *file_name = NULL; int line = 0; # if KMP_USE_HWLOC - if (depth < 0) { + if (depth < 0 && __kmp_affinity_dispatch->get_api_type() == KMPAffinity::HWLOC) { if (__kmp_affinity_verbose) { KMP_INFORM(AffUsingHwloc, "KMP_AFFINITY"); } @@ -3947,6 +3931,7 @@ __kmp_aux_affinity_initialize(void) # if KMP_USE_HWLOC else if (__kmp_affinity_top_method == affinity_top_method_hwloc) { + KMP_ASSERT(__kmp_affinity_dispatch->get_api_type() == KMPAffinity::HWLOC); if (__kmp_affinity_verbose) { KMP_INFORM(AffUsingHwloc, "KMP_AFFINITY"); } @@ -4233,6 +4218,7 @@ __kmp_affinity_uninitialize(void) __kmp_hwloc_topology = NULL; } # endif + KMPAffinity::destroy_api(); } |