Questionable advice

S

SG

Yes. Who wants to have lockless copy-on-write has to write it. Pointer
to atomic refcount feels simplest candidate. If to propose one to boost
then it probably eventually lands in C++.

std::shared_ptr makes implementing COW fairly easy. Just saying.
 
J

James Kanze

std::shared_ptr makes implementing COW fairly easy. Just saying.

Thread-safe? (std::shared_ptr is thread safe, but I have my
doubts about a COW class which uses it.)
 
W

woodbrian77

That's as it ought to be, the most basic components like standard library
containers should contain no locking or any other synchronization so
appropriate synchronization can be applied on the correct level.

In this regard, if std::shared_ptr is always synchronizing access to the
reference counter and there is no template policy or something to switch it
off (I haven't studied it, so don't know), then I would say it is
inherently broken (does not adhere to the zero overhead principle of
C/C++). Note that any event of unneeded synchronization will become
progressively more and more expensive in future massively multicore
machines).

I haven't found a better place to ask this. Is there any terminology
for an approach that minimizes multithreading in applications and
relies on the OS to make use of the available hardware?
 
I

Ian Collins

I haven't found a better place to ask this. Is there any terminology
for an approach that minimizes multithreading in applications and
relies on the OS to make use of the available hardware?

The only thing that comes close would be OpenMP.
 
S

SG

Thread-safe? (std::shared_ptr is thread safe, but I have my
doubts about a COW class which uses it.)

Yes. As long as all concurrent const-accesses to the pointee are
thread-safe, the COW wrapper will be as thread-safe. Read/write
accessors might look like this:

T const& read() const
{
return *(this->sptr);
}

T& write()
{
if (!this->sptr.unique())
this->sptr = make_shared<T>(read());
assert(this->sptr.unique());
return *(this->sptr);
}

and you're done. This will be thread-safe in the useful definition
kind of way of thread-safety. By that I mean that two threads working
on the same _wrapper_ object still requires synchronization. So, in
case there is no concurrent access to such a wrapper, everything is
fine. In particular, the uniqueness won't suddenly be gone between
the test and the return in the write function. For that to happen we
would need an unsynchronized concurrent access to that wrapper.
Threads accessing _different_ wrapper objects that share the same
pointee is perfectly fine. The worst thing that could happen here is
one unnecessary copy in case many threads want write access at the
exact same time because every thread would create a copy and the
original value would be discarded by every thread.

So, one does not need to fiddle around with atomics or mutexes to get
copy-on-write right. std::shared_ptr does that for you.

Cheers!
SG
 
Ö

Öö Tiib

"Multiprocessing"

+1. It can make things very parallel without multi-threading. Especially
on Unixes with cheap 'fork()'.

Odd that Brian asked it. I had impression that Brian's marshaling
library was (at least partially) meant for usage in inter-process
communication that is essential for nontrivial cases of multi-processing.
 
W

woodbrian77

Or "event-driven programming".
Or "Multiprogramming" as Raymond calls it in "The Art of
Unix Programming":

I watched a video about Go language and got the
impression it goes overboard with multithread
support. I try to minimize use of threads.
Another answer to my question might be some of
the Boost libs that are alternatives to threads.
 
Ö

Öö Tiib

Why do you "try to minimize use of threads"? That's a pretty
silly goal, really.

Might be I misunderstand something but ...

"try to minimize use of threads": keep major parts of
products single-threaded and use multitasking (and savvy workforce)
only where it gives major performance advantages.

That strategy seems to be not overly silly because:

1) the number of programmers who can come out with sequential
algorithm of passable quality (or to maintain one) seems to be lot
bigger than number of programmers who can produce and to deal with
explicitly parallel algorithm for same problem.

2) different algorithms are less or more parallelizable and the number
of highly parallelizable algorithms seems to be lot smaller than
number of serial algorithms that are rather difficult to turn into
parallel. The serial-only algorithms are usually more robust and
also more efficient if ran single-threaded.

3) synchronization and thread safety costs something and it may be
not rational to pay that price where it is not needed (things may
still be "embarrassingly parallel").

4) despite decades of work by compiler researchers, automatic
parallelization has had only limited success.

I agree with rest of the post that suggested to learn and to understand
multithreading as marvelous tool, just that strategy to minimize its
usage do not contradict with that.
 
J

Jorgen Grahn

Might be I misunderstand something but ...

"try to minimize use of threads": keep major parts of
products single-threaded and use multitasking (and savvy workforce)
only where it gives major performance advantages.

That's how I understood him too. I have seen to many people apply
threads automatically[1] and ending up with really fragile code
because they weren't up to the task.

/Jorgen

[1] "I read from N file descriptors, so obviously I need N
threads." Or "I'll make my API blocking, because the caller
can simply call it from its own thread."
 
W

woodbrian77

Might be I misunderstand something but ...
"try to minimize use of threads": keep major parts of
products single-threaded and use multitasking (and savvy workforce)
only where it gives major performance advantages.

That strategy seems to be not overly silly because:

1) the number of programmers who can come out with sequential
algorithm of passable quality (or to maintain one) seems to be lot
bigger than number of programmers who can produce and to deal with
explicitly parallel algorithm for same problem.

2) different algorithms are less or more parallelizable and the number
of highly parallelizable algorithms seems to be lot smaller than
number of serial algorithms that are rather difficult to turn into
parallel. The serial-only algorithms are usually more robust and
also more efficient if ran single-threaded.

They may be more robust because they are more approachable
by someone who doesn't have days/weeks to review your code.
You may be too familiar with the code and be missing something
that they will be able to spot.
3) synchronization and thread safety costs something and it may be
not rational to pay that price where it is not needed (things may
still be "embarrassingly parallel").

Here you refer to runtime I think and previously you mentioned savvy/sophisticated workers who may cost a lot, but who
sometimes leave behind difficult to reproduce/fix bugs for the
next programmer.
4) despite decades of work by compiler researchers, automatic
parallelization has had only limited success.

I agree with rest of the post that suggested to learn and to understand
multithreading as marvelous tool, just that strategy to minimize its
usage do not contradict with that.


You do a good job of defending this perspective. I'm not
arguing to remove anything from C++ related to threading.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top