aboutsummaryrefslogtreecommitdiff
path: root/runtime/src/kmp_affinity.cpp
diff options
context:
space:
mode:
authorJonathan Peyton <jonathan.l.peyton@intel.com>2016-11-14 21:08:35 +0000
committerJonathan Peyton <jonathan.l.peyton@intel.com>2016-11-14 21:08:35 +0000
commitd4da538d3c5ec0ee9d22d417fff9ec3721c0fa32 (patch)
tree7996f994e9cdafa3340acb16d4ac5a3ec9607074 /runtime/src/kmp_affinity.cpp
parent76755788c3fe74c8d5382133fb32d5f917ae2ce3 (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.cpp98
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();
}