MESSAGE
DATE | 2015-04-02 |
FROM | Ruben Safir
|
SUBJECT | Subject: [LIU Comp Sci] Fwd: omp pthread madness
|
From owner-learn-outgoing-at-mrbrklyn.com Thu Apr 2 13:22:01 2015 Return-Path: X-Original-To: archive-at-mrbrklyn.com Delivered-To: archive-at-mrbrklyn.com Received: by mrbrklyn.com (Postfix) id 5F458161165; Thu, 2 Apr 2015 13:22:01 -0400 (EDT) Delivered-To: learn-outgoing-at-mrbrklyn.com Received: by mrbrklyn.com (Postfix, from userid 28) id 3DD16161174; Thu, 2 Apr 2015 13:22:01 -0400 (EDT) Delivered-To: learn-at-nylxs.com Received: from l2mail1.panix.com (l2mail1.panix.com [166.84.1.75]) by mrbrklyn.com (Postfix) with ESMTP id 5D15A161165; Thu, 2 Apr 2015 13:21:36 -0400 (EDT) Received: from mailbackend.panix.com (mailbackend.panix.com [166.84.1.89]) by l2mail1.panix.com (Postfix) with ESMTP id 4AF238B7D; Thu, 2 Apr 2015 12:22:40 -0400 (EDT) Received: from [10.0.0.19] (unknown [96.57.23.82]) by mailbackend.panix.com (Postfix) with ESMTPSA id 17DA712D9B; Thu, 2 Apr 2015 12:17:40 -0400 (EDT) Message-ID: <551D6BA3.8020209-at-panix.com> Date: Thu, 02 Apr 2015 12:17:39 -0400 From: Ruben Safir User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.3.0 MIME-Version: 1.0 To: learn-at-nylxs.com, Hangout Subject: [LIU Comp Sci] Fwd: omp pthread madness References: <551cfdde$0$3035$426a34cc-at-news.free.fr> In-Reply-To: <551cfdde$0$3035$426a34cc-at-news.free.fr> X-Forwarded-Message-Id: <551cfdde$0$3035$426a34cc-at-news.free.fr> Content-Type: multipart/mixed; boundary="------------030607060602070805010502" Sender: owner-learn-at-mrbrklyn.com Precedence: bulk Reply-To: learn-at-mrbrklyn.com
This is a multi-part message in MIME format. --------------030607060602070805010502 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit
--------------030607060602070805010502 Content-Type: message/rfc822; name="omp pthread madness.eml" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="omp pthread madness.eml"
Path: reader1.panix.com!panix!not-for-mail From: ruben Newsgroups: comp.unix.programmer Subject: omp pthread madness Date: Wed, 1 Apr 2015 04:40:44 +0000 (UTC) Organization: PANIX Public Access Internet and UNIX, NYC Message-ID: NNTP-Posting-Host: 96.57.23.82 Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Trace: reader1.panix.com 1427863244 27151 96.57.23.82 (1 Apr 2015 04:40:44 GMT) X-Complaints-To: abuse-at-panix.com NNTP-Posting-Date: Wed, 1 Apr 2015 04:40:44 +0000 (UTC) To: mrbrklyn-at-panix.com User-Agent: Pan/0.139 (Sexual Chocolate; GIT bf56508 git://git.gnome.org/pan2) Xref: panix comp.unix.programmer:234408
I'm doing this test program with OMP threads and I'm getting a very odd result which I have no idea where this is happening.
i set up a shared workspace for the threads called wordspace[MAX_SPACE] and what should happen is that it gets filled with coordinate points. PI can be estimated by a formula based on how many at random as they are picked, end up within a circle.
When I construct it without threads, it does a decent job of predicting about 3.14 etc.
With OMP, it is giving numbers in the 6 zone. I don't see anything that would make my random selection change, nor do I see anything else, so I'm at a loss, and admittedly can use some mentoring here, not only to understand my mistake, but to understand the theory so I don't repeat it.
pi_lib.h
#ifndef MONTI_PI #define MONTI_PI
#define MEMORY_SPACE 10000
struct point{ double x; double y; };
struct point * random_point(void); double calc_pi(void); int count_inside(void);
#endif
pid_lib.c
/* Question 4.18 from the operating systems HW from Text * OS Ed 9 * Class Operating SYstems at LIU * Prog M Ghriger * * Ruben Safir - Student * ********************************************************/ #include #include #include "pi_lib.h" #include #include
struct point workspace[MEMORY_SPACE]; long seed = 0; long inside_the_circle = 0; struct timespec ts; struct point sample;
struct point * random_point(void) { int i; double x,y;
if(seed == 0){ clock_gettime(CLOCK_REALTIME, &ts); seed = ts.tv_nsec; srand(seed); } for (i = 0; i < MEMORY_SPACE; i++){ //fprintf( stderr, "Error %d\n", __LINE__); //x = ((double)rand()) % (double)1000000 ; x = rand() % 1000000 ; x = x / (double)1000000;
// printf ("x==> %F", x); //y = ((double)rand())% (double)1000000 ; y = rand()% 10000000 ; y = y / (double)10000000; // printf(" y==> %F\n", y); workspace[i].x = x; workspace[i].y = y; } return &workspace[0]; }
int count_inside(void) { int i = 0; double d; for(i = 0; i < MEMORY_SPACE; i++){ d = sqrt(pow(workspace[i].x, 2.0) + pow(workspace[i].y, 2.0)); // printf ("distance => %f\n", d); if (d <= 1.0) inside_the_circle++; } return inside_the_circle; }
double calc_pi(){ return 4.0 * (( double)inside_the_circle/ (double)MEMORY_SPACE) ; }
monty_pi_omp.c
#include #include #include "pi_lib.h" #include #include
void * wrapper(void*); double pi;
int main(int argc, char * argv[]){ double pi; #pragma omp parallel { random_point(); count_inside(); }
pi = calc_pi(); printf("Pi is estimated at ==> %f\n\n", pi);
return 1; }
and just for comparison
this is monty_pi.c
#include #include #include "pi_lib.h" #include
void * wrapper(void*);
int main(int argc, char * argv[]){ double pi; pthread_attr_t attr; pthread_attr_init(&attr); pthread_t tid; void * arg = NULL; pthread_create(&tid, &attr, wrapper, arg); pthread_join(tid, NULL);
pi = calc_pi(); printf("Pi is estimated at ==> %f\n\n", pi);
return 1; }
void * wrapper(void * arg){ random_point(); count_inside(); pthread_exit(arg); }
and this was the makefile
XX:=gcc CXXFLAGS:=-Wall -g -pg LDFLAGS:= -pg -pthread -fopenmp
monty_pi_omp : monty_pi_omp.o pi_lib.o $(CXX) $(CXXFLAGS) $(LDFLAGS) -o monty_pi_omp.exe monty_pi_omp.o pi_lib.o
monty_pi : monty_pi.o pi_lib.o $(CXX) $(CXXFLAGS) $(LDFLAGS) -o monty_pi.exe monty_pi.o pi_lib.o
monty_pi_omp.o : monty_pi_omp.c pi_lib.h $(CXX) $(CXXFLAGS) $(LDFLAGS) -c monty_pi_omp.c
monty_pi.o : monty_pi.c pi_lib.h $(CXX) $(CXXFLAGS) $(LDFLAGS) -c monty_pi.c
pi_lib.o : pi_lib.h pi_lib.c $(CXX) $(CXXFLAGS) $(LDFLAGS) -c pi_lib.c
include make.deps make.deps: *.c; ${CXX} ${CXXFLAGS} -M *.c >$-at-
--------------030607060602070805010502 Content-Type: message/rfc822; name="Re: omp pthread madness.eml" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="Re: omp pthread madness.eml"
Path: reader1.panix.com!panix!goblin3!goblin.stu.neva.ru!bolzen.all.de!fu-berlin.de!uni-berlin.de!not-for-mail From: jt-at-toerring.de (Jens Thoms Toerring) Newsgroups: comp.unix.programmer Subject: Re: omp pthread madness Date: 1 Apr 2015 10:04:59 GMT Organization: Freie Universitaet Berlin Message-ID: References: X-Trace: news.uni-berlin.de DCoAdi/S212qvOJ0Q27iqATTSWmnicAlHKxhwj/bKAm1zW X-Orig-Path: not-for-mail User-Agent: tin/2.1.1-20120623 ("Mulindry") (UNIX) (Linux/3.2.0-4-amd64 (x86_64)) Xref: panix comp.unix.programmer:234409
ruben wrote: > I'm doing this test program with OMP threads and I'm getting a very odd > result which I have no idea where this is happening.
> i set up a shared workspace for the threads called wordspace[MAX_SPACE] > and what should happen is that it gets filled with coordinate points. PI > can be estimated by a formula based on how many at random as they are > picked, end up within a circle.
> When I construct it without threads, it does a decent job of predicting > about 3.14 etc.
> With OMP, it is giving numbers in the 6 zone. I don't see anything that > would make my random selection change, nor do I see anything else, so I'm > at a loss, and admittedly can use some mentoring here, not only to > understand my mistake, but to understand the theory so I don't repeat it.
Let me guess: you have a 2-core processor (or have set the OMP_NUM_THREADS environment variable set to 2).
The obvious problem is that you have (at least) 2 threads which uncoordinatedly write into shared, global variables. That's always a recipe for disaster, with or without OpenMP. Consider what's going on here: you have two threads that both write to your 'workspace' (which isn't the major problem, but only be- cause what gets written in there are random numbers, and it doesn't help either) and you have these threads, when done with filling 'workspace', both increment 'count_inside'. So, if you have two threads, you will end up with a value of 'count_inside' that is roughly twice the value it would have had when there would only have been a single thread (since you did the coun- ting twice). And thus you end up with a value for pi that is too large by roughly a factor of 2.
If your intention is to do the whole calculation twice (or as many times as you have cores or processors) and then e.g average over the results from the different threads to in- crease the precision, the way to go might be to have a single function, with 'workspace' and 'inside_count' etc. as local variables, that does the calculations and, when finished, adds the calculated value of pi to a global variable, which you protect from concurent accesses with e.g. a mutex. Then, when all threads are done, divide that variable's value by the number of threads (the omp_get_num_threads() function will tell you how many you're using). And use rand_r() instead of rand() since, as the man page explicitely states, rand() is not thread-safe! (When using threads you better check for each function you use if it's thread-safe and if it's not, either use the replacement function with '_r' appended to the name or, if such a replacement function does not exist, do not use that function at all.) Regards, Jens -- \ Jens Thoms Toerring ___ jt-at-toerring.de \__________________________ http://toerring.de
--------------030607060602070805010502 Content-Type: message/rfc822; name="Re: omp pthread madness.eml" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="Re: omp pthread madness.eml"
Path: reader1.panix.com!panix!not-for-mail From: ruben Newsgroups: comp.unix.programmer Subject: Re: omp pthread madness Date: Thu, 2 Apr 2015 06:24:10 +0000 (UTC) Organization: PANIX Public Access Internet and UNIX, NYC Message-ID: References: NNTP-Posting-Host: 96.57.23.82 Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Trace: reader1.panix.com 1427955850 844 96.57.23.82 (2 Apr 2015 06:24:10 GMT) X-Complaints-To: abuse-at-panix.com NNTP-Posting-Date: Thu, 2 Apr 2015 06:24:10 +0000 (UTC) User-Agent: Pan/0.139 (Sexual Chocolate; GIT bf56508 git://git.gnome.org/pan2) Xref: panix comp.unix.programmer:234416
On Wed, 01 Apr 2015 10:04:59 +0000, Jens Thoms Toerring wrote:
> The obvious problem is that you have (at least) 2 threads which > uncoordinatedly write into shared, global variables.
who is it uncoordinated. I couldn't think of anything that is shared that would upset the final result.
--------------030607060602070805010502 Content-Type: message/rfc822; name="Re: omp pthread madness.eml" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="Re: omp pthread madness.eml"
Path: reader1.panix.com!panix!not-for-mail From: ruben Newsgroups: comp.unix.programmer Subject: Re: omp pthread madness Date: Thu, 2 Apr 2015 06:29:53 +0000 (UTC) Organization: PANIX Public Access Internet and UNIX, NYC Message-ID: References: NNTP-Posting-Host: 96.57.23.82 Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Trace: reader1.panix.com 1427956193 844 96.57.23.82 (2 Apr 2015 06:29:53 GMT) X-Complaints-To: abuse-at-panix.com NNTP-Posting-Date: Thu, 2 Apr 2015 06:29:53 +0000 (UTC) User-Agent: Pan/0.139 (Sexual Chocolate; GIT bf56508 git://git.gnome.org/pan2) Xref: panix comp.unix.programmer:234417
On Wed, 01 Apr 2015 10:04:59 +0000, Jens Thoms Toerring wrote:
> The obvious problem is that you have (at least) 2 threads which > uncoordinatedly write into shared, global variables.
How is it uncoordinated. I couldn't think of anything that is shared that would upset the final result.
It is filling he space with random point. Even if it steps on itself, it shouldn't cause a statistical bias.
--------------030607060602070805010502 Content-Type: message/rfc822; name="Re: omp pthread madness.eml" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="Re: omp pthread madness.eml"
Path: reader1.panix.com!panix!goblin2!goblin.stu.neva.ru!feeder.erje.net!eu.feeder.erje.net!fu-berlin.de!uni-berlin.de!not-for-mail From: jt-at-toerring.de (Jens Thoms Toerring) Newsgroups: comp.unix.programmer Subject: Re: omp pthread madness Date: 2 Apr 2015 07:54:23 GMT Organization: Freie Universitaet Berlin Message-ID: References: X-Trace: news.uni-berlin.de CN+MolLzw+c7Ah1N/Ysy/wqQ3uyFQlPNHj809rhqtMSURU X-Orig-Path: not-for-mail User-Agent: tin/2.1.1-20120623 ("Mulindry") (UNIX) (Linux/3.2.0-4-amd64 (x86_64)) Xref: panix comp.unix.programmer:234418
ruben wrote: > On Wed, 01 Apr 2015 10:04:59 +0000, Jens Thoms Toerring wrote:
> > The obvious problem is that you have (at least) 2 threads which > > uncoordinatedly write into shared, global variables.
> How is it uncoordinated. I couldn't think of anything that is shared > that would upset the final result.
> It is filling he space with random point. Even if it steps on itself, it > shouldn't cause a statistical bias.
But after filling 'workspace' with your random_point() function you also have all threads run the count_insider() function. And in that you increment the shared variable 'inside_the_circle'. So this is now done twice (or as many threads you have) as often as with a single-threaded program, so you will get a result for pi that's about twice (or as many threads you have) as large as ex- pected. Just move the line where you call count_inside() from the omp block to directly after it and see what happens. Or divide the result you get for pi by the number of threads.
Regards, Jens -- \ Jens Thoms Toerring ___ jt-at-toerring.de \__________________________ http://toerring.de
--------------030607060602070805010502 Content-Type: message/rfc822; name="Re: omp pthread madness.eml" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="Re: omp pthread madness.eml"
Path: reader1.panix.com!panix!usenet.stanford.edu!fu-berlin.de!uni-berlin.de!not-for-mail From: jt-at-toerring.de (Jens Thoms Toerring) Newsgroups: comp.unix.programmer Subject: Re: omp pthread madness Date: 2 Apr 2015 14:26:14 GMT Organization: Freie Universitaet Berlin Message-ID: References: X-Trace: news.uni-berlin.de oOQhjetmLDjkgJM/camWDQFmarqOiUjqN2Q6M9AHmLu52P X-Orig-Path: not-for-mail User-Agent: tin/2.1.1-20120623 ("Mulindry") (UNIX) (Linux/3.2.0-4-amd64 (x86_64)) Xref: panix comp.unix.programmer:234420
ruben wrote: > On Wed, 01 Apr 2015 10:04:59 +0000, Jens Thoms Toerring wrote:
> > The obvious problem is that you have (at least) 2 threads which > > uncoordinatedly write into shared, global variables.
> How is it uncoordinated. I couldn't think of anything that is shared > that would upset the final result.
It is uncoordinated because it's unpredictable in which sequence the threads will access these global variables and, worse, they may do it at the same time.
Are you aware of the 'sig_atomic_t' type in C? The reason for its existence is that reads from or writes to even something simple as an integer isn't "atomic", i.e. one thread may have updated parts of that integer (say one of the bytes it consists of) when another thread gets sche- duled and tries to read this integer which is now in some strange state. So the second thread will get some more or less random value instead of what the programmer expected. Or let's have thread 1 having started to update the integer, then thread 2 comes along, updates all of it and then we're back in thread 1 that writes the parts it hadn't got around to before. Result? A random value in memory. What's special about the 'sig_atomic_t' is that with that type this can't happen, you're guaranteed that a thread of execution can't be interupted while it writes or reads it.
Now, if this already can happen with integers, it clearly isn't any better with floats or doubles. And your program assumes obviously that the random values you write into the 'workspace' have a well-definen upper limit (looks like it's 1). Unccor- dinated writes to the same location may result in values that doesn't satisfy this condition. And in other cases values may be smaller. You probably won't notice it, but it can happen and add some additional noise to the results of your calculations.
Another place were things can go wrong is with your 'inside_the_circle' variable. There's a non-vanishing chance that, for the line
inside_the_circle++;
the following happens: thread 1 reads its value to increment it. Along comes thread 2 and possibly increments it several times before thread 1 gets to finish what it set out to do. Then it will increment ther value it had read and write it into memory, thereby destroying all the work the other thread had done in between.
Or you may end up with a situation where the compiler optimizes your program in way that during the count_inside() function the value of 'inside_the_circle' is kept in a CPU register and only this copy is incremented. It's then only written out at the very end of the function. And then, when both threads run that function at the same time, they both increment their copy in the CPU register and write it out at the end, with the thread getting there last simply overwri- ting whatever any other thread had put there before.
So you can't trust what this variable is set to when both threads are done with it.
In any case, if you'd run your program several times with the same seed for the random generator you'll rather likely end up with different results. Your program has become in- deterministic with its result depending on subtle timing differences in how the threads get scheduled or access your global variables. That's something one tries to avoid like the plague. Regards, Jens -- \ Jens Thoms Toerring ___ jt-at-toerring.de \__________________________ http://toerring.de
--------------030607060602070805010502 Content-Type: message/rfc822; name="Re: omp pthread madness.eml" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="Re: omp pthread madness.eml"
Path: reader1.panix.com!panix!news.linkpendium.com!news.linkpendium.com!news.glorb.com!peer02.iad.highwinds-media.com!news.highwinds-media.com!feed-me.highwinds-media.com!post02.iad.highwinds-media.com!fx11.iad.POSTED!not-for-mail Newsgroups: comp.unix.programmer From: Greg Martin Subject: Re: omp pthread madness References: Organization: SoftSprocket User-Agent: slrn/1.0.1 (Linux) Message-ID: NNTP-Posting-Host: 184.66.24.99 X-Complaints-To: internet.abuse-at-sjrb.ca X-Trace: 1427899418 184.66.24.99 (Wed, 01 Apr 2015 14:43:38 UTC) NNTP-Posting-Date: Wed, 01 Apr 2015 14:43:38 UTC Date: Wed, 01 Apr 2015 14:43:38 GMT X-Received-Bytes: 2327 X-Received-Body-CRC: 811301577 Xref: panix comp.unix.programmer:234411
On 2015-04-01, ruben wrote: > I'm doing this test program with OMP threads and I'm getting a very odd > result which I have no idea where this is happening. > > i set up a shared workspace for the threads called wordspace[MAX_SPACE] > and what should happen is that it gets filled with coordinate points. PI > can be estimated by a formula based on how many at random as they are > picked, end up within a circle. > > When I construct it without threads, it does a decent job of predicting > about 3.14 etc. > > With OMP, it is giving numbers in the 6 zone. I don't see anything that > would make my random selection change, nor do I see anything else, so I'm > at a loss, and admittedly can use some mentoring here, not only to > understand my mistake, but to understand the theory so I don't repeat it. > OpenMP often requires more then simply declaring a portion of code parallel. I'm not an expert in its use but have looked into it a bit. Below is an example where a variable, sum, is created that will be unique in each thread then summed.
https://computing.llnl.gov/tutorials/openMP/#REDUCTION
#include #include #include
int main () { static long num_steps = 100000; double step = 1.0 / (double) num_steps;
double sum; double start = omp_get_wtime ();
#pragma omp parallel { #pragma omp for reduction(+:sum) schedule(static) for (int i = 0; i < num_steps; ++i) { double x = (i + 0.5) * step; sum += 4.0 / (1.0 + x * x); }
}
double end = omp_get_wtime ();
double pi = step * sum;
printf ("PI = %.*f\n", DBL_DIG, pi); printf ("time = %.*f\n", DBL_DIG, end - start);
return 0;
}
--------------030607060602070805010502 Content-Type: message/rfc822; name="Re: omp pthread madness.eml" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="Re: omp pthread madness.eml"
Path: reader1.panix.com!panix!usenet.stanford.edu!news.glorb.com!peer01.iad.highwinds-media.com!news.highwinds-media.com!feed-me.highwinds-media.com!post01.iad.highwinds-media.com!fx07.iad.POSTED!not-for-mail X-Newsreader: xrn 9.03-beta-14-64bit Sender: scott-at-dragon.sl.home (Scott Lurndal) From: scott-at-slp53.sl.home (Scott Lurndal) Reply-To: slp53-at-pacbell.net Subject: Re: omp pthread madness Newsgroups: comp.unix.programmer References: Message-ID: X-Complaints-To: abuse-at-usenetserver.com NNTP-Posting-Date: Wed, 01 Apr 2015 15:41:08 UTC Organization: UsenetServer - www.usenetserver.com Date: Wed, 01 Apr 2015 15:41:08 GMT X-Received-Bytes: 2585 X-Received-Body-CRC: 820403566 Xref: panix comp.unix.programmer:234412
Greg Martin writes: >On 2015-04-01, ruben wrote: >> I'm doing this test program with OMP threads and I'm getting a very odd >> result which I have no idea where this is happening. >> >> i set up a shared workspace for the threads called wordspace[MAX_SPACE] >> and what should happen is that it gets filled with coordinate points. PI >> can be estimated by a formula based on how many at random as they are >> picked, end up within a circle. >> >> When I construct it without threads, it does a decent job of predicting >> about 3.14 etc. >> >> With OMP, it is giving numbers in the 6 zone. I don't see anything that >> would make my random selection change, nor do I see anything else, so I'm >> at a loss, and admittedly can use some mentoring here, not only to >> understand my mistake, but to understand the theory so I don't repeat it. >> >OpenMP often requires more then simply declaring a portion of code >parallel. I'm not an expert in its use but have looked into it a bit. >Below is an example where a variable, sum, is created that will be >unique in each thread then summed. > >https://computing.llnl.gov/tutorials/openMP/#REDUCTION > >#include >#include >#include > > >int main () { > static long num_steps = 100000; > > double step = 1.0 / (double) num_steps; > > double sum; > > double start = omp_get_wtime (); > >#pragma omp parallel > { >#pragma omp for reduction(+:sum) schedule(static) > for (int i = 0; i < num_steps; ++i) { > double x = (i + 0.5) * step; > sum += 4.0 / (1.0 + x * x); > } > > } > > double end = omp_get_wtime (); > > double pi = step * sum; > > printf ("PI = %.*f\n", DBL_DIG, pi); > printf ("time = %.*f\n", DBL_DIG, end - start); > > return 0; > >} >
And this should result in the compiler generating SIMD instructions to provide parallelism; it's not multithreaded.
--------------030607060602070805010502 Content-Type: message/rfc822; name="Re: omp pthread madness.eml" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="Re: omp pthread madness.eml"
Path: reader1.panix.com!panix!usenet.stanford.edu!news.glorb.com!peer02.iad.highwinds-media.com!news.highwinds-media.com!feed-me.highwinds-media.com!post02.iad.highwinds-media.com!fx05.iad.POSTED!not-for-mail Newsgroups: comp.unix.programmer From: Greg Martin Subject: Re: omp pthread madness References: Organization: SoftSprocket User-Agent: slrn/1.0.1 (Linux) Message-ID: NNTP-Posting-Host: 184.66.24.99 X-Complaints-To: internet.abuse-at-sjrb.ca X-Trace: 1427904626 184.66.24.99 (Wed, 01 Apr 2015 16:10:26 UTC) NNTP-Posting-Date: Wed, 01 Apr 2015 16:10:26 UTC Date: Wed, 01 Apr 2015 16:10:26 GMT X-Received-Bytes: 2898 X-Received-Body-CRC: 1164840089 Xref: panix comp.unix.programmer:234413
On 2015-04-01, Scott Lurndal wrote: > Greg Martin writes: >>On 2015-04-01, ruben wrote: >>> I'm doing this test program with OMP threads and I'm getting a very odd >>> result which I have no idea where this is happening. >>> >>> i set up a shared workspace for the threads called wordspace[MAX_SPACE] >>> and what should happen is that it gets filled with coordinate points. PI >>> can be estimated by a formula based on how many at random as they are >>> picked, end up within a circle. >>> >>> When I construct it without threads, it does a decent job of predicting >>> about 3.14 etc. >>> >>> With OMP, it is giving numbers in the 6 zone. I don't see anything that >>> would make my random selection change, nor do I see anything else, so I'm >>> at a loss, and admittedly can use some mentoring here, not only to >>> understand my mistake, but to understand the theory so I don't repeat it. >>> >>OpenMP often requires more then simply declaring a portion of code >>parallel. I'm not an expert in its use but have looked into it a bit. >>Below is an example where a variable, sum, is created that will be >>unique in each thread then summed. >> >>https://computing.llnl.gov/tutorials/openMP/#REDUCTION >> >>#include >>#include >>#include >> >> >>int main () { >> static long num_steps = 100000; >> >> double step = 1.0 / (double) num_steps; >> >> double sum; >> >> double start = omp_get_wtime (); >> >>#pragma omp parallel >> { >>#pragma omp for reduction(+:sum) schedule(static) >> for (int i = 0; i < num_steps; ++i) { >> double x = (i + 0.5) * step; >> sum += 4.0 / (1.0 + x * x); >> } >> >> } >> >> double end = omp_get_wtime (); >> >> double pi = step * sum; >> >> printf ("PI = %.*f\n", DBL_DIG, pi); >> printf ("time = %.*f\n", DBL_DIG, end - start); >> >> return 0; >> >>} >> > > And this should result in the compiler generating SIMD > instructions to provide parallelism; it's not multithreaded.
Where do you get that from? Everything I've read indicates that #pragma omp parallel will spawn threads.
-- http://www.softsprocket.com
--------------030607060602070805010502 Content-Type: message/rfc822; name="Re: omp pthread madness.eml" Content-Transfer-Encoding: 8bit Content-Disposition: attachment; filename="Re: omp pthread madness.eml"
Path: reader1.panix.com!panix!goblin1!goblin.stu.neva.ru!proxad.net!feeder1-2.proxad.net!cleanfeed2-b.proxad.net!nnrp2-1.free.fr!not-for-mail Newsgroups: comp.unix.programmer From: Nicolas George Subject: Re: omp pthread madness Sender: george-at-phare.invalid (Nicolas George) X-Newsreader: Flrn (0.9.20070704) References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset=iso-8859-1 Date: 02 Apr 2015 08:29:19 GMT Message-ID: <551cfdde$0$3035$426a34cc-at-news.free.fr> Organization: Guest of ProXad - France NNTP-Posting-Date: 02 Apr 2015 10:29:19 CEST NNTP-Posting-Host: 129.199.129.80 X-Trace: 1427963359 news-4.free.fr 3035 129.199.129.80:34857 X-Complaints-To: abuse-at-proxad.net Xref: panix comp.unix.programmer:234419
ruben , dans le message , a ?crit?: > pid_lib.c
Apart from the obvious mistakes in thread handling, there are quite a few stylistic issues in your code, I do not know if you are aware of them and just wrote it that way to illustrate your problem or if they are genuine mistakes.
> long seed = 0; > long inside_the_circle = 0;
Do not use long (unless you are interacting with an old API that uses it), it is just useless. Use types adapted for the use of your numbers (off_t for file offsets, size_t for indices in memory objects) or their magnitude (intXX_t, int_leastXX_t if you want to be sure).
> struct timespec ts;
Why does it need to be global?
> struct point sample; > > struct point * random_point(void) > { > int i; > double x,y; > > if(seed == 0){ > clock_gettime(CLOCK_REALTIME, &ts); > seed = ts.tv_nsec; > srand(seed); > } > for (i = 0; i < MEMORY_SPACE; i++){ > //fprintf( stderr, "Error %d\n", __LINE__); > //x = ((double)rand()) % (double)1000000 ;
> x = rand() % 1000000 ;
Do you know that some pseudo random numbers generators will perform very badly with modulus. It could even be catastrophic with a power of two modulus. Even nowadays, some libc still use theses PRNGs, for compatibility's sake.
> x = x / (double)1000000;
Since you are dividing by a float anyway, do it the right way: RAND_MAX.
> > // printf ("x==> %F", x); > //y = ((double)rand())% (double)1000000 ; > y = rand()% 10000000 ; > y = y / (double)10000000; > // printf(" y==> %F\n", y); > workspace[i].x = x; > workspace[i].y = y; > } >
> return &workspace[0];
Why are you returning a value that is never used?
> } > > int count_inside(void) > { > int i = 0; > double d; > for(i = 0; i < MEMORY_SPACE; i++){ > d = sqrt(pow(workspace[i].x, 2.0) + pow(workspace[i].y, > 2.0)); > // printf ("distance => %f\n", d); > if (d <= 1.0) > inside_the_circle++; > } > return inside_the_circle; > } > > double calc_pi(){ > return 4.0 * (( double)inside_the_circle/ (double)MEMORY_SPACE) ; > } > > > > monty_pi_omp.c > > #include > #include > #include "pi_lib.h" > #include > #include > > void * wrapper(void*); > double pi; > > int main(int argc, char * argv[]){ > double pi; > #pragma omp parallel > {
> random_point(); > count_inside();
Why do you feel the need of storing each point and then counting them? Generate the point and count them directly, no need for a huge memory buffer.
> } > > pi = calc_pi(); > printf("Pi is estimated at ==> %f\n\n", pi); >
> return 1;
Did you program fail?
> }
--------------030607060602070805010502--
|
|