C++, Pthreads & other threading technologies

30 wyświetleń
Przejdź do pierwszej nieodczytanej wiadomości

Bartlomiej Jacek Kubica

nieprzeczytany,
14 maj 2009, 13:57:4214.05.2009
do

Hello,

I started wondering about some details.
I've written a few programs in C++ that use Pthreads.
In Linux and the g++ compiler we have to use the ``-pthread'' option -
*not only* to link the threading library, but to do other changes to some underlying
tools.

Ok, but - when I use Boost threads or TBB, they're just some wrapping over
Pthreads, right ? But ``-pthread'' is not put to the programs anywhere
when we use them.
So, how on Earth does it work ? For example - which variant of the errno
variable is used in programs using Boost or TBB - the one usied in POSIX
threads or the ``ordinary'' one ?

In particular, it seems that in the degenerate case of using only one
thread (but creating this thread explicitely !), Boost threads are
slightly faster than Pthreads - linking Boost libraries does not prevent
aggressive optimizations when compiling, while using ``-pthread'' does.
I observed small, but probably not accidental differences in my
experiments.

Thanks in advance for any clarifications or comments.

Best regards
Bartlomiej Kubica

David Schwartz

nieprzeczytany,
14 maj 2009, 20:38:4914.05.2009
do
On May 14, 10:57 am, Bartlomiej Jacek Kubica
<bkub...@mion.elka.pw.edu.pl> wrote:

> Ok, but - when I use Boost threads or TBB, they're just some wrapping over
> Pthreads, right ? But ``-pthread'' is not put to the programs anywhere
> when we use them.

That sounds like a bug, unless you have platform-specific knowledge
that that's not needed.

> In particular, it seems that in the degenerate case of using only one
> thread (but creating this thread explicitely !), Boost threads are
> slightly faster than Pthreads - linking Boost libraries does not prevent
> aggressive optimizations when compiling, while using ``-pthread'' does.

On what platform does '-pthread' disable any optimizations? Almost
every known optimization that fails with threads fails with other
cases as well.

DS

Bartlomiej Jacek Kubica

nieprzeczytany,
15 maj 2009, 10:58:4515.05.2009
do
On Thu, 14 May 2009, David Schwartz wrote:

> On May 14, 10:57 am, Bartlomiej Jacek Kubica
> <bkub...@mion.elka.pw.edu.pl> wrote:
>
>> Ok, but - when I use Boost threads or TBB, they're just some wrapping over
>> Pthreads, right ? But ``-pthread'' is not put to the programs anywhere
>> when we use them.
>
> That sounds like a bug, unless you have platform-specific knowledge
> that that's not needed.

Dear David,

Now I'm even more puzzled than I was.
I checked Makefiles for the examples in the TBB library and:
- none of them uses -pthread,
- examples for parallel_for link the library -lpthread,
- other examples don't use any of them.

So, what the heck ! Which variant is correct ?!

As for Boost threads, here I do not have a reliable example, but I never
heard that.
Also, I checked now that one of the files in the Boost headers defines
_REENTRANT.

> ---


> On what platform does '-pthread' disable any optimizations? Almost
> every known optimization that fails with threads fails with other
> cases as well.

Doesn't it ? I was convinced -pthread (as -fopenmp) disables some
``aggressive compiler optimizations''. But now that you mention it...
possibly I was wrong...

Best regards
Bartlomiej Kubica

David Schwartz

nieprzeczytany,
15 maj 2009, 14:25:2115.05.2009
do
On May 15, 7:58 am, Bartlomiej Jacek Kubica

<bkub...@mion.elka.pw.edu.pl> wrote:
> On Thu, 14 May 2009, David Schwartz wrote:
> > On May 14, 10:57 am, Bartlomiej Jacek Kubica
> > <bkub...@mion.elka.pw.edu.pl> wrote:
>
> >> Ok, but - when I use Boost threads or TBB, they're just some wrapping over
> >> Pthreads, right ? But ``-pthread'' is not put to the programs anywhere
> >> when we use them.
>
> > That sounds like a bug, unless you have platform-specific knowledge
> > that that's not needed.
>
> Dear David,
>
> Now I'm even more puzzled than I was.
> I checked Makefiles for the examples in the TBB library and:
> - none of them uses -pthread,
> - examples for parallel_for link the library -lpthread,
> - other examples don't use any of them.
>
> So, what the heck ! Which variant is correct ?!

If you use '-lpthread', that's obviously based on platform-specific
knowledge. There's no standard that says '-lpthread' does anything in
particular. So probably the omission of '-pthread' is probably also
based on the platform-specific knowledge that it's not needed in this
case.

> > On what platform does '-pthread' disable any optimizations? Almost
> > every known optimization that fails with threads fails with other
> > cases as well.

> Doesn't it ? I was convinced -pthread (as -fopenmp) disables some
> ``aggressive compiler optimizations''. But now that you mention it...
> possibly I was wrong...

I've heard this discussed several times, but people typically were
able to find ways the optimizations in question broke non-threaded
code as well. So the optimizations were either not done or
unconditionally removed.

There are only a very few rare optimizations that break only on
threaded code. And most of these are no longer optimizations on modern
hardware anyway.

One possible example might be implementing code like:

if (j>0) i=j;

as if it was written:

i = (j>0) ? j : i;

If you don't see why this is a problem, consider what happens if:

if(j>0) pthread_mutex_lock(mutex_that_protects_i);
if(j>0) i=j;
if(j>0) pthread_mutex_unlock(mutex_that_protects_i);

is implement as:

if(j>0) pthread_mutex_lock(mutex_that_protects_i);
i = (j>0) ? j : i;
if(j>0) pthread_mutex_unlock(mutex_that_protects_i);

Notice how the optimized code can read 'i' and then write it back
without holding the lock, causing a change made by another thread to
be lost.

But this usually isn't an optimization on modern hardware anyway since
the 'optimized' code must pull 'i' into cache even if j<=0.

DS

Bartlomiej Jacek Kubica

nieprzeczytany,
17 maj 2009, 09:09:5617.05.2009
do
On Fri, 15 May 2009, David Schwartz wrote:

> ---


> If you use '-lpthread', that's obviously based on platform-specific
> knowledge. There's no standard that says '-lpthread' does anything in
> particular. So probably the omission of '-pthread' is probably also
> based on the platform-specific knowledge that it's not needed in this
> case.

Dear David,

Not really. Option ``-lwhatever'' in GCC means ``link the whatever
library'', so it has a perfectly precise meaning.
The problem is that to use POSIX threads correctly, linking a library is
(at least on most platforms) not sufficient.

> ---


> I've heard this discussed several times, but people typically were
> able to find ways the optimizations in question broke non-threaded
> code as well. So the optimizations were either not done or
> unconditionally removed.

Shame for me that I haven't. Thanks !

> There are only a very few rare optimizations that break only on
> threaded code. And most of these are no longer optimizations on modern
> hardware anyway.
>
> One possible example might be implementing code like:

> ---

Indeed, I cant't think of any optimizations that are not possible in MT
environment and possible for a single thread (but I'm not a compiler
expert !).

But, actually, I'm not convinced by your example, too.
Either there should be an explicit memory barrier (e. g. by using a lock),
that would disable the optimization or I see no reason to do the
optimization even if there are several threads (if they do not change this
variable...). That's if the optimization made sense, obviously, as -
according to what you've written - it does not.
Oh, well, also it is possible that some compilers' developers don't know
that...


After this all, still, I don't know if programs using TBB or Boost
threads should use the ``-pthread'' option or not. Anybody knows ?

Best regards
Bartlomiej

David Schwartz

nieprzeczytany,
17 maj 2009, 16:30:3517.05.2009
do
On May 17, 6:09 am, Bartlomiej Jacek Kubica
<bkub...@mion.elka.pw.edu.pl> wrote:

> On Fri, 15 May 2009, David Schwartz wrote:

> > If you use '-lpthread', that's obviously based on platform-specific
> > knowledge. There's no standard that says '-lpthread' does anything in
> > particular. So probably the omission of '-pthread' is probably also
> > based on the platform-specific knowledge that it's not needed in this
> > case.

> Dear David,

> Not really. Option ``-lwhatever'' in GCC means ``link the whatever
> library'', so it has a perfectly precise meaning.

Right, but we're talking about '-lpthread' which loads a library named
'libpthread' which might do anything at all. There is no platform-
independent way to know what it does.

> The problem is that to use POSIX threads correctly, linking a library is
> (at least on most platforms) not sufficient.

And even if it was, there's no guarantee that it's named 'pthread' or
that the library you get with '-lpthread' has anything to do with
POSIX threads.


> But, actually, I'm not convinced by your example, too.
> Either there should be an explicit memory barrier (e. g. by using a lock),
> that would disable the optimization or I see no reason to do the
> optimization even if there are several threads (if they do not change this
> variable...). That's if the optimization made sense, obviously, as -
> according to what you've written - it does not.
> Oh, well, also it is possible that some compilers' developers don't know
> that...

I'm not sure you understood my example. The point is that an
optimization may create a read followed by a write back in cases where
the unoptimized code caused no reference at all. For example, a
compiler that didn't have to support multiple thread could optimize:

j=i+1;

to:

i++;
j=i;
i--;

Who knows, on some platform that might actually be an optimization.
However, on a multi-threaded platform, if two threads run this code
concurrently, they may get different values for 'j' even though no
thread touches 'i'. An optimizer for code that runs on multiple
threads basically cannot add new memory writes ever (though it can
move them, duplicate them, or consolidate them), even if it is an
optimization to do so.

This code, naively, does not write to 'i', so it may not be optimized
to do so.

> After this all, still, I don't know if programs using TBB or Boost
> threads should use the ``-pthread'' option or not. Anybody knows ?

If it is required for thread-safe code on your platform, then yes. If
not, then no. IMO, you should always use it because even requirements
on a single platform can change over time.

DS

Dave Butenhof

nieprzeczytany,
19 maj 2009, 09:00:3619.05.2009
do
David Schwartz wrote:
> On May 15, 7:58 am, Bartlomiej Jacek Kubica
> <bkub...@mion.elka.pw.edu.pl> wrote:
>> On Thu, 14 May 2009, David Schwartz wrote:
>>> On May 14, 10:57 am, Bartlomiej Jacek Kubica
>>> <bkub...@mion.elka.pw.edu.pl> wrote:
>>>> Ok, but - when I use Boost threads or TBB, they're just some wrapping over
>>>> Pthreads, right ? But ``-pthread'' is not put to the programs anywhere
>>>> when we use them.
>>> That sounds like a bug, unless you have platform-specific knowledge
>>> that that's not needed.
>> Dear David,
>>
>> Now I'm even more puzzled than I was.
>> I checked Makefiles for the examples in the TBB library and:
>> - none of them uses -pthread,
>> - examples for parallel_for link the library -lpthread,
>> - other examples don't use any of them.
>>
>> So, what the heck ! Which variant is correct ?!
>
> If you use '-lpthread', that's obviously based on platform-specific
> knowledge. There's no standard that says '-lpthread' does anything in
> particular. So probably the omission of '-pthread' is probably also
> based on the platform-specific knowledge that it's not needed in this
> case.

In fact, that's not correct.

The POSIX/UNIX standard says that 'c99 -lpthread' is the only correct
idiom to portably link an application using pthread interfaces. There is
no standard -pthread, or -mt, or -D_REENTRANT, though various systems
use those alternatives (and more). If the implementation requires
compile time setup for thread safety, then the c99 driver must infer
that from the appearance of -lpthread. (In standard POSIX terms, if the
implementation supports threads there's no such thing as a
"non-threaded" environment, or any formal mechanism to allow compilation
that's not thread safe, so compile-time options should be irrelevant,
and you only need the symbols in scope if you're using them.)

Note that XCU doesn't require the existence of an actual "libpthread*"
file, and allows the compiler to search for pthread symbols even in the
absence of -lpthread -- but doesn't require it. A "strictly conforming"
POSIX threaded application is written in c99 dialect, and built using
"c99 -lpthread". (Nothing else can be "strictly conforming".)

In practice, though, few people probably use 'c99' -- they use gcc, or
aCC, or cc, or whatever, and technically this rule doesn't apply.

Still, the point is that there IS a standard that says -lpthread is a
portable guaranteed way to ensure that pthread symbols are searched, so
you stand corrected. ;-)

Whether anyone uses that, or cares, is a different matter entirely. But,
in theory, there's no difference between theory and practice... ;-)

David Schwartz

nieprzeczytany,
19 maj 2009, 19:09:4819.05.2009
do
On May 19, 6:00 am, Dave Butenhof <david.buten...@hp.com> wrote:

> Still, the point is that there IS a standard that says -lpthread is a
> portable guaranteed way to ensure that pthread symbols are searched, so
> you stand corrected. ;-)

Yes, I do. Thanks for the correction.

DS

Geoff Clare

nieprzeczytany,
21 maj 2009, 08:27:5521.05.2009
do
Dave Butenhof wrote:

> The POSIX/UNIX standard says that 'c99 -lpthread' is the only correct
> idiom to portably link an application using pthread interfaces. There is
> no standard -pthread, or -mt, or -D_REENTRANT, though various systems
> use those alternatives (and more). If the implementation requires
> compile time setup for thread safety, then the c99 driver must infer
> that from the appearance of -lpthread.

That _was_ the situation in the 2001 standard, but it has changed
in the new 2008 standard. Now you can use

getconf POSIX_V7_THREADS_CFLAGS

to find out what compile-time flags (e.g. -D_REENTRANT) should be
used with c99, and

getconf POSIX_V7_THREADS_LDFLAGS

to find out what link-time flags should be used. (There is no
POSIX_V7_THREADS_LIBS variable because the standard pthread library
is still -lpthread).

--
Geoff Clare <net...@gclare.org.uk>

Odpowiedz wszystkim
Odpowiedz autorowi
Przekaż dalej
Nowe wiadomości: 0