- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
def.h
---------
#include
#define STOP 4
extern int myvar;
void SetValue(int val);
int Count();
int GetValue();
int *GetAddress(void);
work.c
-----------
#include "def.h"
int myvar;
#pragma omp threadprivate(myvar)
int *GetAddress(void) { return &myvar;}
int GetValue() { return myvar;}
void SetValue(int val) { myvar = val;}
int Count()
{
myvar++;
if (myvar == STOP)
return 0;
else
return 1;
}
main.c
-----------
#include
#include "def.h"
int main()
{
int cnt=0;
omp_set_num_threads(4);
SetValue(-1);
printf("Before parallel region: myvar address: %p value: %d ",&myvar, myvar);
#pragma intel omp parallel taskq shared(cnt)
while (Count())
{
#pragma intel omp task captureprivate(cnt)
{
SetValue(cnt);
printf("Thread %d myvar address: %p value: %d GetAddress: %p GetValue: %d ",
omp_get_thread_num(), &myvar, myvar, GetAddress(), GetValue());
}
cnt++;
}
return 1;
}
When I make and execute this I get the following output:
Before parallel region: myvar address: 0x804b83c value: -1
Thread 0 myvar address: 0x804b83c value: 0 GetAddress: 0x804b83c GetValue: 0
Thread 3 myvar address: 0x804b83c value: 0 GetAddress: 0x805c180 GetValue: 1
Thread 1 myvar address: 0x804b83c value: 0 GetAddress: 0x805c380 GetValue: 2
Thread 2 myvar address: 0x804b83c value: 0 GetAddress: 0x805c580 GetValue: 3
This is not what I expected. When threads start to execute parallel region (tasks) any reference to a myvar should be to the same, threadprivate copy of the global variable. What I got here is that if I reference myvar by its name in main.c it works with the global variable, and when I call functions defined in work.c it works with a threadprivate copies.
In my opinion this is a bug. Can you confirm this?
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
This is an user error/mis-understanding. In the def.h file, you need to mark "myvar" as threadprivate to get expected behavior. Below isthe correct usage of threadprivate for your test . In addition, you need to change the order of including def.h in work.c to get the legalsyntax of using "pragma omp threadprivate" for extern int myvar.
Xinmin Tian (Intel)
// def.h
#include
#define STOP 4
extern int myvar;
#pragma omp threadprivate(myvar)
void SetValue(int val);
int Count();
int GetValue();
int *GetAddress(void);
// work.c
int myvar;
#pragma omp threadprivate(myvar)
#include "def.h"
int *GetAddress(void) { return &myvar;}
int GetValue() { return myvar;}
void SetValue(int val) { myvar = val;}
int Count() { myvar++; if (myvar == STOP) return 0; else return 1;}
// main.c
#include
#include "def.h"
int main()
{ int cnt=0;
omp_set_num_threads(4);
SetValue(-1);
printf("Before parallel region: myvar address: %p value: %d
",&myvar, myvar);
#pragma intel omp parallel taskq shared(cnt)
while (Count()) {
#pragma intel omp task captureprivate(cnt)
{
SetValue(cnt);
printf("Thread %d myvar address: %p value: %d GetAddress: %p GetValue: %d
", omp_get_thread_num(), &myvar, myvar, GetAddress(), GetValue());
}
cnt++;
}
return 1;
}
Intel C++ Compiler for applications running on IA-32, Version Mainline Beta
Build x
Built Jan 2 2008 18:11:27 by xtian on SC12SSG005 in C:/cmplr/dev_hpo/dev
Copyright (C) 1985-2007 Intel Corporation. All rights reserved.
main.c
C: estsmain.c(10): (col. 1) remark: TASK CONSTRUCT WAS PARALLELIZED.
C: estsmain.c(8): (col. 1) remark: PARALLEL TASKQ CONSTRUCT WAS PARALLELIZED.
work.c
Microsoft Incremental Linker Version 7.10.3077
Copyright (C) Microsoft Corporation. All rights reserved.
-out:main.exe
-nodefaultlib:libguide_stats.lib
-nodefaultlib:libguide40_stats.lib
-defaultlib:libguide.lib
main.obj
work.obj
Before parallel region: myvar address: 0042C11C value: -1
Thread 2 myvar address: 00447B80 value: 0 GetAddress: 00447B80 GetValue: 0
Thread 1 myvar address: 00448280 value: 1 GetAddress: 00448280 GetValue: 1
Thread 0 myvar address: 0042C11C value: 3 GetAddress: 0042C11C GetValue: 3
Thread 3 myvar address: 00448380 value: 2 GetAddress: 00448380 GetValue: 2
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for the answer!
Before I wrote this post I tried all the combinations of where to put threadprivate directive, but the trick is in the order in which I include header file.
I will test this in a few days just to confirm that everything is OK.
Have a nice time!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks again.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page