Skip to content
This repository was archived by the owner on Apr 23, 2020. It is now read-only.

Commit 66ddc21

Browse files
Enable tasks dependencies hashmaps resizing.
Patch by viroulep (Philippe Virouleau) Differential Revision: https://reviews.llvm.org/D67447 git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@372879 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 2b135c5 commit 66ddc21

File tree

3 files changed

+103
-11
lines changed

3 files changed

+103
-11
lines changed

runtime/src/kmp.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2181,10 +2181,9 @@ struct kmp_dephash_entry {
21812181
typedef struct kmp_dephash {
21822182
kmp_dephash_entry_t **buckets;
21832183
size_t size;
2184-
#ifdef KMP_DEBUG
2184+
size_t generation;
21852185
kmp_uint32 nelements;
21862186
kmp_uint32 nconflicts;
2187-
#endif
21882187
} kmp_dephash_t;
21892188

21902189
typedef struct kmp_task_affinity_info {

runtime/src/kmp_taskdeps.cpp

Lines changed: 64 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,64 @@ static inline kmp_depnode_t *__kmp_node_ref(kmp_depnode_t *node) {
5454

5555
enum { KMP_DEPHASH_OTHER_SIZE = 97, KMP_DEPHASH_MASTER_SIZE = 997 };
5656

57+
size_t sizes[] = { 997, 2003, 4001, 8191, 16001, 32003, 64007, 131071, 270029 };
58+
const size_t MAX_GEN = 8;
59+
5760
static inline kmp_int32 __kmp_dephash_hash(kmp_intptr_t addr, size_t hsize) {
5861
// TODO alternate to try: set = (((Addr64)(addrUsefulBits * 9.618)) %
5962
// m_num_sets );
6063
return ((addr >> 6) ^ (addr >> 2)) % hsize;
6164
}
6265

66+
static kmp_dephash_t *__kmp_dephash_extend(kmp_info_t *thread,
67+
kmp_dephash_t *current_dephash) {
68+
kmp_dephash_t *h;
69+
70+
size_t gen = current_dephash->generation + 1;
71+
if (gen >= MAX_GEN)
72+
return current_dephash;
73+
size_t new_size = sizes[gen];
74+
75+
kmp_int32 size_to_allocate =
76+
new_size * sizeof(kmp_dephash_entry_t *) + sizeof(kmp_dephash_t);
77+
78+
#if USE_FAST_MEMORY
79+
h = (kmp_dephash_t *)__kmp_fast_allocate(thread, size_to_allocate);
80+
#else
81+
h = (kmp_dephash_t *)__kmp_thread_malloc(thread, size_to_allocate);
82+
#endif
83+
84+
h->size = new_size;
85+
h->nelements = current_dephash->nelements;
86+
h->buckets = (kmp_dephash_entry **)(h + 1);
87+
h->generation = gen;
88+
89+
// insert existing elements in the new table
90+
for (size_t i = 0; i < current_dephash->size; i++) {
91+
kmp_dephash_entry_t *next;
92+
for (kmp_dephash_entry_t *entry = current_dephash->buckets[i]; entry; entry = next) {
93+
next = entry->next_in_bucket;
94+
// Compute the new hash using the new size, and insert the entry in
95+
// the new bucket.
96+
kmp_int32 new_bucket = __kmp_dephash_hash(entry->addr, h->size);
97+
if (entry->next_in_bucket) {
98+
h->nconflicts++;
99+
}
100+
entry->next_in_bucket = h->buckets[new_bucket];
101+
h->buckets[new_bucket] = entry;
102+
}
103+
}
104+
105+
// Free old hash table
106+
#if USE_FAST_MEMORY
107+
__kmp_fast_free(thread, current_dephash);
108+
#else
109+
__kmp_thread_free(thread, current_dephash);
110+
#endif
111+
112+
return h;
113+
}
114+
63115
static kmp_dephash_t *__kmp_dephash_create(kmp_info_t *thread,
64116
kmp_taskdata_t *current_task) {
65117
kmp_dephash_t *h;
@@ -81,10 +133,9 @@ static kmp_dephash_t *__kmp_dephash_create(kmp_info_t *thread,
81133
#endif
82134
h->size = h_size;
83135

84-
#ifdef KMP_DEBUG
136+
h->generation = 0;
85137
h->nelements = 0;
86138
h->nconflicts = 0;
87-
#endif
88139
h->buckets = (kmp_dephash_entry **)(h + 1);
89140

90141
for (size_t i = 0; i < h_size; i++)
@@ -97,7 +148,13 @@ static kmp_dephash_t *__kmp_dephash_create(kmp_info_t *thread,
97148
#define ENTRY_LAST_MTXS 1
98149

99150
static kmp_dephash_entry *
100-
__kmp_dephash_find(kmp_info_t *thread, kmp_dephash_t *h, kmp_intptr_t addr) {
151+
__kmp_dephash_find(kmp_info_t *thread, kmp_dephash_t **hash, kmp_intptr_t addr) {
152+
kmp_dephash_t *h = *hash;
153+
if (h->nelements != 0
154+
&& h->nconflicts/h->size >= 1) {
155+
*hash = __kmp_dephash_extend(thread, h);
156+
h = *hash;
157+
}
101158
kmp_int32 bucket = __kmp_dephash_hash(addr, h->size);
102159

103160
kmp_dephash_entry_t *entry;
@@ -122,11 +179,9 @@ __kmp_dephash_find(kmp_info_t *thread, kmp_dephash_t *h, kmp_intptr_t addr) {
122179
entry->mtx_lock = NULL;
123180
entry->next_in_bucket = h->buckets[bucket];
124181
h->buckets[bucket] = entry;
125-
#ifdef KMP_DEBUG
126182
h->nelements++;
127183
if (entry->next_in_bucket)
128184
h->nconflicts++;
129-
#endif
130185
}
131186
return entry;
132187
}
@@ -232,7 +287,7 @@ static inline kmp_int32 __kmp_depnode_link_successor(kmp_int32 gtid,
232287

233288
template <bool filter>
234289
static inline kmp_int32
235-
__kmp_process_deps(kmp_int32 gtid, kmp_depnode_t *node, kmp_dephash_t *hash,
290+
__kmp_process_deps(kmp_int32 gtid, kmp_depnode_t *node, kmp_dephash_t **hash,
236291
bool dep_barrier, kmp_int32 ndeps,
237292
kmp_depend_info_t *dep_list, kmp_task_t *task) {
238293
KA_TRACE(30, ("__kmp_process_deps<%d>: T#%d processing %d dependencies : "
@@ -352,7 +407,7 @@ __kmp_process_deps(kmp_int32 gtid, kmp_depnode_t *node, kmp_dephash_t *hash,
352407

353408
// returns true if the task has any outstanding dependence
354409
static bool __kmp_check_deps(kmp_int32 gtid, kmp_depnode_t *node,
355-
kmp_task_t *task, kmp_dephash_t *hash,
410+
kmp_task_t *task, kmp_dephash_t **hash,
356411
bool dep_barrier, kmp_int32 ndeps,
357412
kmp_depend_info_t *dep_list,
358413
kmp_int32 ndeps_noalias,
@@ -552,7 +607,7 @@ kmp_int32 __kmpc_omp_task_with_deps(ident_t *loc_ref, kmp_int32 gtid,
552607
__kmp_init_node(node);
553608
new_taskdata->td_depnode = node;
554609

555-
if (__kmp_check_deps(gtid, node, new_task, current_task->td_dephash,
610+
if (__kmp_check_deps(gtid, node, new_task, &current_task->td_dephash,
556611
NO_DEP_BARRIER, ndeps, dep_list, ndeps_noalias,
557612
noalias_dep_list)) {
558613
KA_TRACE(10, ("__kmpc_omp_task_with_deps(exit): T#%d task had blocking "
@@ -633,7 +688,7 @@ void __kmpc_omp_wait_deps(ident_t *loc_ref, kmp_int32 gtid, kmp_int32 ndeps,
633688
kmp_depnode_t node = {0};
634689
__kmp_init_node(&node);
635690

636-
if (!__kmp_check_deps(gtid, &node, NULL, current_task->td_dephash,
691+
if (!__kmp_check_deps(gtid, &node, NULL, &current_task->td_dephash,
637692
DEP_BARRIER, ndeps, dep_list, ndeps_noalias,
638693
noalias_dep_list)) {
639694
KA_TRACE(10, ("__kmpc_omp_wait_deps(exit): T#%d has no blocking "
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// RUN: %libomp-compile && env KMP_ENABLE_TASK_THROTTLING=0 %libomp-run
2+
3+
#include<omp.h>
4+
#include<stdlib.h>
5+
#include<string.h>
6+
7+
// The first hashtable static size is 997
8+
#define NUM_DEPS 4000
9+
10+
11+
int main()
12+
{
13+
int *deps = calloc(NUM_DEPS, sizeof(int));
14+
int i;
15+
int failed = 0;
16+
17+
#pragma omp parallel
18+
#pragma omp master
19+
{
20+
for (i = 0; i < NUM_DEPS; i++) {
21+
#pragma omp task firstprivate(i) depend(inout: deps[i])
22+
{
23+
deps[i] = 1;
24+
}
25+
#pragma omp task firstprivate(i) depend(inout: deps[i])
26+
{
27+
deps[i] = 2;
28+
}
29+
}
30+
}
31+
32+
for (i = 0; i < NUM_DEPS; i++) {
33+
if (deps[i] != 2)
34+
failed++;
35+
}
36+
37+
return failed;
38+
}

0 commit comments

Comments
 (0)