I'm new to OpenMP and try to write a postorder tree traversal using OpenMP TASK.
The tree is simple:
Node 2 (root) is the parent of 3, 4
Node 3 is the parent of 5, 6
Node 4 is the parent of 7, 8
The output shows that all the work is done by thread 0, but every pdf online says it should be parallel. Is this an issue of some sort of thread safe?
The code is
#include <omp.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct Node Node;
struct Node {
int id;
Node* left;
Node* right;
};
void process(int n) {
printf("I'm now on node %d working\n", n);
for (int i = 0; i < 50000000; i++) {int j = 1; j++;}
printf("I'm now on node %d working finished\n", n);
}
void traverseTree(Node * t) {
#pragma omp task
{
if (t->left) {
printf("Thread %d now go to node %d\n", omp_get_thread_num(), t->left->id);
traverseTree(t->left);
}
}
#pragma omp task
{
if (t->right) {
printf("Thread %d now go to node %d\n", omp_get_thread_num(), t->right->id);
traverseTree(t->right);
}
}
#pragma omp taskwait
printf("I'm thread %d, now on node %d working\n", omp_get_thread_num(), t->id);
process(t->id);
}
int main() {
//build the tree
int n_nodes = 9;
Node nodes[n_nodes];
for (int i = 2; i < n_nodes; i++) {
nodes[i].id = i;
if (nodes[i].id * 2 < n_nodes) {
nodes[i].left = &nodes[nodes[i].id*2-1];
nodes[i].right = &nodes[nodes[i].id*2];
} else {
nodes[i].left = NULL;
nodes[i].right = NULL;
}
}
#pragma omp prallel num_threads(24)
{
#pragma omp single
{
traverseTree(&nodes[2]);
}
}
}
Can anyone explain this?
Well, it is due to ... a typing mistake. You should write:
#pragma omp parallel num_threads(24)
// ~~~~~~~~
By the way, optimizing compilers will optimize out such a loop (ie. remove it):
for (int i = 0; i < 50000000; i++) {int j = 1; j++;}
If it takes time, this means optimizations are disabled. This is OK to debug a program but not to profile it. Please consider using the -O3
flag with GCC/Clang/ICC or /O2
with MSVC.