I am trying to process linked list data in parallel with OpenMP in C++. I'm pretty new to OpenMP and pretty rusty with C++. What I want to do is get several threads to break up the linked list, and output the data of the Nodes in their particular range. I don't care about the order in which the output occurs. If I can get this working, I want to replace the simple output with some actual processing of the Node data.
I've found several things on the internet (including a few questions on this site) and from what I found, I cobbled together a code like this:
#include <iostream>
#include <omp.h>
// various and sundry other stuff ...
struct Node {
int data;
Node* next;
};
int main() {
struct Node *newHead;
struct Node *head = new Node;
struct Node *currNode;
int n;
int tid;
//create a bunch of Nodes in linked list with "data" ...
// traverse the linked list:
// examine data
#pragma omp parallel private(tid)
{
currNode = head;
tid=omp_get_thread_num();
#pragma omp single
{
while (currNode) {
#pragma omp task firstprivate(currNode)
{
cout << "Node data: " << currNode->data << " " << tid << "\n";
} // end of pragma omp task
currNode = currNode->next;
} // end of while
} //end of pragma omp single
} // end of pragma omp parallel
// clean up etc. ...
} // end of main
So I run:
>: export OMP_NUM_THREADS=6
>: g++ -fopenmp ll_code.cpp
>: ./a.out
And the output is:
Node data: 5 0
Node data: 10 0
Node data: 20 0
Node data: 30 0
Node data: 35 0
Node data: 40 0
Node data: 45 0
Node data: 50 0
Node data: 55 0
Node data: 60 0
Node data: 65 0
Node data: 70 0
Node data: 75 0
So, tid is always 0. And that means, unless I'm really misunderstanding something, only one thread did anything with the linked list, and so the linked list was not traversed in parallel at all.
When I get rid of single
, the code fails with a seg fault. I have tried moving a few variables in and out of the OpenMP directive scopes, with no change. Changing the number of threads has no effect. How can this be made to work?
A secondary question: Some sites say the firstprivate(currNode)
is necessary and others say currNode
is firstprivate
by default. Who is right?