summaryrefslogtreecommitdiffstats
path: root/openmp/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
commit1cdd87adfd379d178c2aeae59b5bb05079ef67f5 (patch)
tree3ea5a3378d309ca3307495e7ccab89d7aa337d66 /openmp/runtime/src/kmp_affinity.cpp
parent22fc0078095c5806aba560a3ec9add1e9c11e647 (diff)
downloadbcm5719-llvm-1cdd87adfd379d178c2aeae59b5bb05079ef67f5.tar.gz
bcm5719-llvm-1cdd87adfd379d178c2aeae59b5bb05079ef67f5.zip
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 llvm-svn: 286890
Diffstat (limited to 'openmp/runtime/src/kmp_affinity.cpp')
-rw-r--r--openmp/runtime/src/kmp_affinity.cpp98
1 files changed, 42 insertions, 56 deletions
diff --git a/openmp/runtime/src/kmp_affinity.cpp b/openmp/runtime/src/kmp_affinity.cpp
index 93299b53e0a..f09c3cdac93 100644
--- a/openmp/runtime/src/kmp_affinity.cpp
+++ b/openmp/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();
}
OpenPOWER on IntegriCloud