Intel® Moderncode for Parallel Architectures
Support for developing parallel programming applications on Intel® Architecture.

firstprivate is hungry

ifx
Beginner
329 Views
Hi,
i am learning openmp and i want to parallelize one part of my simulation routine with linked list structure. Following some examples from the net, i modified my code, but it does not work according my expectations. The parallel part of the code is draining my memory. I need to iterate several times through the complete linked list. Every time when the "firstprivate" makes a private copy of the Item from the linked list, it is taking some part of the memory, but after the job is done and one "task" is closed, the memory is not released. Is it normal or am i doing something wrong? How can i solve this?

thank you for your tips. test example: (compiled with: icc -g -O0 -openmp -o test ./test.cc )

critical part of test routine:
[cpp]for(i=1;i<=1000;i++)  // MORE interations needs MORE memory
{
pP = pFirst;
#pragma omp parallel num_threads(2)
{
#pragma omp single nowait
{
while (pP != NULL)
{
#pragma omp task private(l) firstprivate(pP)
{
//do some dummy job
l = pP->nr;
pP->y = l;
}
pP = pP->pNext;
}
} // end of single nowait
} // end of parallel region
} // end of for
[/cpp]

Complete test routine:
ATTENTION!: following example can block your PC.

[cpp]#include 
#include
#include "omp.h"

struct ITEM
{
double z, y;
int nr;
ITEM *pNext; // pointer to next
ITEM *pPrev; //pointer to previous
};

/********** prot. *********/
void AppendItem(ITEM *pP);
void RemoveItem(ITEM *pP);
void DeleteAllItems(void);

// Init
ITEM *pFirst, *pLast;
ITEM *pP;
ITEM *pTemp;

int main()
{
int l, i;

// create linked list
for(l=1;l<=1000;l++){
pP = new ITEM; // get mem for item
pP->nr = l;
AppendItem(pP);
}

for(i=1;i<=10000;i++)
{
pP = pFirst;
#pragma omp parallel num_threads(2)
{
#pragma omp single nowait
{
while (pP != NULL)
{
#pragma omp task private(l) firstprivate(pP)
{
//do some dummy job
l = pP->nr;
pP->y = l;
}
pP = pP->pNext;
}
} // end of single nowait
} // end of parallel region
}
DeleteAllItems();
return 0;
}

// Appends a node to the end of the list
void AppendItem(ITEM *pP)
{
if (pFirst == NULL) {
pFirst = pP;
pP->pPrev = NULL;
}
else {
pLast->pNext = pP;
pP->pPrev = pLast;
}
pLast = pP;
pP->pNext = NULL;
}

// Removes the specified node from the list
void RemoveItem(ITEM *pP)
{
if (pP->pPrev == NULL) pFirst = pP->pNext;
else pP->pPrev->pNext = pP->pNext;
if (pP->pNext == NULL) pLast = pP->pPrev;
else pP->pNext->pPrev = pP->pPrev;
}

// Deletes the entire list
void DeleteAllItems()
{
while (pFirst != NULL){
RemoveItem(pFirst);
RemoveItem(pP);}
}
[/cpp]
0 Kudos
1 Reply
Om_S_Intel
Employee
329 Views
Quoting - ifx
Hi,
i am learning openmp and i want to parallelize one part of my simulation routine with linked list structure. Following some examples from the net, i modified my code, but it does not work according my expectations. The parallel part of the code is draining my memory. I need to iterate several times through the complete linked list. Every time when the "firstprivate" makes a private copy of the Item from the linked list, it is taking some part of the memory, but after the job is done and one "task" is closed, the memory is not released. Is it normal or am i doing something wrong? How can i solve this?

thank you for your tips. test example: (compiled with: icc -g -O0 -openmp -o test ./test.cc )

critical part of test routine:
[cpp]for(i=1;i<=1000;i++)  // MORE interations needs MORE memory
{
pP = pFirst;
#pragma omp parallel num_threads(2)
{
#pragma omp single nowait
{
while (pP != NULL)
{
#pragma omp task private(l) firstprivate(pP)
{
//do some dummy job
l = pP->nr;
pP->y = l;
}
pP = pP->pNext;
}
} // end of single nowait
} // end of parallel region
} // end of for
[/cpp]

Complete test routine:
ATTENTION!: following example can block your PC.

[cpp]#include 
#include
#include "omp.h"

struct ITEM
{
double z, y;
int nr;
ITEM *pNext; // pointer to next
ITEM *pPrev; //pointer to previous
};

/********** prot. *********/
void AppendItem(ITEM *pP);
void RemoveItem(ITEM *pP);
void DeleteAllItems(void);

// Init
ITEM *pFirst, *pLast;
ITEM *pP;
ITEM *pTemp;

int main()
{
int l, i;

// create linked list
for(l=1;l<=1000;l++){
pP = new ITEM; // get mem for item
pP->nr = l;
AppendItem(pP);
}

for(i=1;i<=10000;i++)
{
pP = pFirst;
#pragma omp parallel num_threads(2)
{
#pragma omp single nowait
{
while (pP != NULL)
{
#pragma omp task private(l) firstprivate(pP)
{
//do some dummy job
l = pP->nr;
pP->y = l;
}
pP = pP->pNext;
}
} // end of single nowait
} // end of parallel region
}
DeleteAllItems();
return 0;
}

// Appends a node to the end of the list
void AppendItem(ITEM *pP)
{
if (pFirst == NULL) {
pFirst = pP;
pP->pPrev = NULL;
}
else {
pLast->pNext = pP;
pP->pPrev = pLast;
}
pLast = pP;
pP->pNext = NULL;
}

// Removes the specified node from the list
void RemoveItem(ITEM *pP)
{
if (pP->pPrev == NULL) pFirst = pP->pNext;
else pP->pPrev->pNext = pP->pNext;
if (pP->pNext == NULL) pLast = pP->pPrev;
else pP->pNext->pPrev = pP->pPrev;
}

// Deletes the entire list
void DeleteAllItems()
{
while (pFirst != NULL){
RemoveItem(pFirst);
RemoveItem(pP);}
}
[/cpp]

I think you have discovered an issue with Intel C++ compiler.

Also you are missing "delete pP;" inRemoveItem().I think you need to remove the statement "RemoveItem(pP);" from DeleteAllItems().

0 Kudos
Reply