Tuesday, March 22, 2016

Digest for comp.lang.c++@googlegroups.com - 25 updates in 3 topics

Shiyao Ma <i@introo.me>: Mar 21 09:06PM -0700

Hi,
 
I often see code like this:
 
 
std::mutex mut;
std::conditional_variable cond;
std::queue<int> qi;
 
// producer
void my_producer() {
std::lock_guard<std::mutex> lg(mut);
// do something on qi
cond.notify_one();
}
 
 
// consumer
void my_consumer() {
std::unqiue_lock<std::mutex> ul(mut);
cond.wait(ul, []{return !qi.empty();});
// do something

ul.unlock()
}
 
 
Note that when cond.notify_one() is called, the lock_guard still holds the mutex.
So even cond.wait is wake up, it will soon be put to sleep.
 
I am confused about the above code. Does the above code make sense?
 
 
Regards.
rapotkinnik@gmail.com: Mar 22 03:48AM -0700

вторник, 22 марта 2016 г., 7:06:55 UTC+3 пользователь Shiyao Ma написал:
> So even cond.wait is wake up, it will soon be put to sleep.
 
> I am confused about the above code. Does the above code make sense?
 
> Regards.
Hi, When cond.wait(...) is called mutex has unlocked. When some thread handle notify_one() and step out cond.wait() method mutex became locked again.
sorry for my english!=)
Shiyao Ma <i@introo.me>: Mar 22 07:48AM -0700

I might not clearly express my question.
 
Say, in my original code sample, the producer is:
 
// producer
void my_producer() {
std::lock_guard<std::mutex> lg(mut);
// do something on qi
cond.notify_one();
}
 
But I think a better one would be:
// producer
void my_producer() {
{
std::lock_guard<std::mutex> lg(mut);
// do something on qi
}
cond.notify_one();
}
 
In the latter, when the `notify_one' is called, the `lg' has already unlocked the mutex, so cond.wait in the consumer can successfully get the mutex.
 
However, the former one suffers the problem that when notify_one is called, the mutex has not been released by the lock guard.
 
 
My question is, does the former and the latter make a difference?
 
Seemingly they should, but I often see code written in the former form.
 
Regards.
"Fred.Zwarts" <F.Zwarts@KVI.nl>: Mar 22 04:31PM +0100

"Shiyao Ma" schreef in bericht
news:5bba06b2-80a1-43d1-9e5a-ba073b7f8ead@googlegroups.com...
 
>My question is, does the former and the latter make a difference?
 
>Seemingly they should, but I often see code written in the former form.
 
>Regards.
 
The problem with the second method is that it creates a race condition.
notify_one is called after unlocking the mutex. So, it is not known who (if
any) has locked the mutex. It could be that the reason to call notif_one
has disappeared because another thread has done something with qi already.
In the first method, notif_one is called with the mutex locked, so
immediately when it unlocks the mutex, one of the waiting threads will get
the mutex and do sometghing useful with qi, without the risk that a third
thread will intervene.
"Hans Bos" <hans.bos@xelion.nl>: Mar 22 04:51PM +0100

"Fred.Zwarts" <F.Zwarts@KVI.nl> wrote in message
news:ncrogv$4qi$1@gioia.aioe.org...
>> }
>> cond.notify_one();
>>}
 
...
> immediately when it unlocks the mutex, one of the waiting threads will get
> the mutex and do sometghing useful with qi, without the risk that a third
> thread will intervene.
 
The first method has the same problem. Waking a thread with notify_xxx() and
aquiring the mutex is not an atomic operation.
It is also possible that another thread is waiting for the mutex before
notify_one is called.
 
So there is no guarantee that the condition still holds.
In http://en.cppreference.com/w/cpp/thread/condition_variable/notify_one the
advice is to call the notify_one() without the lock.
 
Regards,
Hans.
SG <s.gesemann@gmail.com>: Mar 22 08:59AM -0700

On Tuesday, March 22, 2016 at 4:32:00 PM UTC+1, F.Zwarts wrote:
> In the first method, notif_one is called with the mutex locked, so
> immediately when it unlocks the mutex, one of the waiting threads will get
> the mutex
 
Is that so? I'm not sure. Suppose there is one blocked consumer thread
because the queue is empty. Then, the producer enters the critical
section to push an item onto the queue. Then, a second consumer that
wasn't blocked tries to enter the critical section. The producer
invokes not_empty_condition.notify_one() to wake up a potentially
blocked consumer and then unlocks the mutex. Is it guaranteed that the
previously blocked consumer thread will be the first to lock the mutex
or could the 2nd consumer thread win the race?
 
I was about to write a response similar to yours and that if the
notification is kept inside the critical section it should be fine to
replace the consumer's while loop
 
std::unique_lock<std::mutex> lck { mut };
while (qi.empty()) {
not_empty_condition.wait(lck);
}
assert(!qi.empty()); // Obviously!
 
to a simple if:
 
std::unique_lock<std::mutex> lck { mut };
if (qi.empty()) {
not_empty_condition.wait(lck);
}
assert(!qi.empty()); // True?!
 
But I'm not so sure about that anymore. Even if the notification is
done while the mutex was locked, another consumer could still win the
race to lock the mutex and "steal" the item off the queue, couldn't
it?
 
I'd recommend to stick with a while loop to be on the safe side
(protecting yourself from spurious awakenings). And once you use while
loops or the equivalent
 
std::unique_lock<std::mutex> lck { mut };
not_empty_condition.wait(lck, [&]{ return !qi.empty(); });
assert(!qi.empty()); // Obviously
 
you could just as well do the notification outside of the critical
section. Whether that makes a difference, I don't know.
 
Cheers!
SG
"Chris M. Thomasson" <nospam@nospam.nospam>: Mar 22 01:16PM -0700

> "Shiyao Ma" wrote in message
> news:84adbe2a-758f-4693-8142-c1b1c44ee808@googlegroups.com...
 
[...]
 
Signaling/broadcasting the condvar while the mutex
is not held is fine: It can be more efficient.
However, on systems that have wait morphing,
signaling/broadcasting while the mutex is held
should not be less efficient.
"Chris M. Thomasson" <nospam@nospam.nospam>: Mar 22 01:19PM -0700

> news:ncs985$13lk$1@gioia.aioe.org...
 
>> "Shiyao Ma" wrote in message
>> news:84adbe2a-758f-4693-8142-c1b1c44ee808@googlegroups.com...
 
[...]
 
> However, on systems that have wait morphing,
> signaling/broadcasting while the mutex is held
> should not be less efficient.
 
FWIW, I recommend the excellent book:
 
https://books.google.com/books?id=_xvnuFzo7q0C&pg=PA82&lpg=PA82#v=onepage&q&f=false
(linked to a relevant section)
Jerry Stuckle <jstucklex@attglobal.net>: Mar 21 09:08PM -0400

On 3/21/2016 4:42 PM, Mr Flibble wrote:
 
> Yes it does.
 
> Go read.
 
> /Flibble
 
Learn to read, troll. You've shown repeatedly in this newsgroup by many
people just how wrong you are - on so many different subjects.
 
Please feel free to continue to make a fool of yourself. You'll be
doing it without me.
 
 
--
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex@attglobal.net
==================
"Öö Tiib" <ootiib@hot.ee>: Mar 22 12:40AM -0700

On Monday, 21 March 2016 20:51:28 UTC+2, Jens Kallup wrote:
> date - a lazy 37 years old non-profit programmer.
> More like a Hobbit.
 
> I don't want to initial a flamewar, sorry.
 
You did not initiate flame war. Some typical communication patterns here.
 
 
> When you spoke over collections - do you mean
> containers? vectors?
 
The "collection" is simply OOP term about one-to-many relation from
viewpoint of that one. May be even raw array in C++.
 
 
> Should I use -std-c++11 ? 14?
> Is Linux gcc 4.9 to old?
 
4.9 is Ok for C++11, take newer compiler if you want C++14, C++1y may
also be worth trying but it is likely something that C++17 actually
won't never be.
Daniel <danielaparker@gmail.com>: Mar 22 09:58AM -0700

On Monday, March 21, 2016 at 3:47:53 PM UTC-4, Jerry Stuckle wrote:
> >> class Square changes the behavior of the Rectangle class.
 
> > Shall we play spot the logical fallacy?
 
> No fallacy - excerpted from real code I've used over the years.
 
The square-rectangle issue has been debated ad nauseam. Uncle Bob" agrees with Mr Flibble :-) More generally, a quick check with google suggests that so do most participants. Most participants find it unsatisfactory that sub-classing Rectangle forces Square to have two attributes when it needs one. And most participants find it unsatisfactory if Square has to violate a Rectangle contract to allow independent setting of width and height.
 
The reason it's debated rather than resolved once-for-all is that, Cardelli notwithstanding, OO is an ad hoc subject, it's not based on theory. OO has it's little principles, such as LSP, but they only go so far.
 
From the point of view of a class designer, nothing is actually gained from sub-classing Square from Rectangle. If there's a need for it, it's always possible to have an abstract base class for both, that defines common behaviour.
 
Daniel
Jerry Stuckle <jstucklex@attglobal.net>: Mar 22 01:09PM -0400

On 3/22/2016 12:58 PM, Daniel wrote:
 
>>> Shall we play spot the logical fallacy?
 
>> No fallacy - excerpted from real code I've used over the years.
 
> The square-rectangle issue has been debated ad nauseam. Uncle Bob" agrees with Mr Flibble :-) More generally, a quick check with google suggests that so do most participants. Most participants find it unsatisfactory that sub-classing Rectangle forces Square to have two attributes when it needs one. And most participants find it unsatisfactory if Square has to violate a Rectangle contract to allow independent setting of width and height.
 
And a lot of people disagree with Mr. Flibble. :) And Google is hardly
a reliable resource; many experts in the field don't bother posting in
forums and newsgroups because they rapidly get tired of the arguments
from know-it-alls.
 
But I'm not going to continue the argument here. There are too many
know-it-alls.
 
> The reason it's debated rather than resolved once-for-all is that, Cardelli notwithstanding, OO is an ad hoc subject, it's not based on theory. OO has it's little principles, such as LSP, but they only go so far.
 
No, OO is not an ad hoc subject. But it does not have strict rules,
either. It is based on theory and has principles such as encapsulation,
inheritance, etc. But it is not tightly standardized like programming
languages.
 
> From the point of view of a class designer, nothing is actually gained from sub-classing Square from Rectangle. If there's a need for it, it's always possible to have an abstract base class for both, that defines common behaviour.
 
That also is debatable. I have done it with great success when I've had
to deal with GUIs. There can be a significant amount of code involved,
and only one small piece (the height/width) is different between the two.
 
 
--
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex@attglobal.net
==================
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Mar 22 05:46PM

On 22/03/2016 01:08, Jerry Stuckle wrote:
> people just how wrong you are - on so many different subjects.
 
> Please feel free to continue to make a fool of yourself. You'll be
> doing it without me.
 
I also suggest you read about "psychological projection" because you
appear to be suffering from it.
 
/Flibble
Wouter van Ooijen <wouter@voti.nl>: Mar 22 06:51PM +0100

Op 22-Mar-16 om 6:09 PM schreef Jerry Stuckle:
 
> That also is debatable. I have done it with great success when I've had
> to deal with GUIs. There can be a significant amount of code involved,
> and only one small piece (the height/width) is different between the two.
 
That smells of implementation sharing, which is commonly recognized as a
bad reason to use (public) inheritance.
 
Wouter
legalize+jeeves@mail.xmission.com (Richard): Mar 22 05:58PM

[Please do not mail me a copy of your followup]
 
Jens Kallup <jkallup@web.de> spake the secret code
> Properties
> - Color
> - Brush...
 
What you want is composition, not inheritance.
 
You want a 'has-a' relationship, not an 'is-a' relationship.
 
A property is *not* a circle.
A property is *not* a rectangle.
 
A rectangle *has* properties.
A circle *has* properties.
--
"The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline>
The Computer Graphics Museum <http://computergraphicsmuseum.org>
The Terminals Wiki <http://terminals.classiccmp.org>
Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com>
Jerry Stuckle <jstucklex@attglobal.net>: Mar 22 02:04PM -0400

On 3/22/2016 1:46 PM, Mr Flibble wrote:
 
> I also suggest you read about "psychological projection" because you
> appear to be suffering from it.
 
> /Flibble
 
Yes, you really do. Because now you're an expert in psychology, also.
 
ROFLMAO!
 
--
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex@attglobal.net
==================
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Mar 22 06:08PM

On 22/03/2016 17:58, Richard wrote:
> A property is *not* a rectangle.
 
> A rectangle *has* properties.
> A circle *has* properties.
 
It makes sense for properties such as Color and Brush to be part of the
Shape base class as presumably all Shapes have these properties.
 
There is a fundamental rule in OOA/D: prefer composition to inheritance.
 
/Flibble
Jerry Stuckle <jstucklex@attglobal.net>: Mar 22 02:09PM -0400

On 3/22/2016 1:51 PM, Wouter van Ooijen wrote:
 
> That smells of implementation sharing, which is commonly recognized as a
> bad reason to use (public) inheritance.
 
> Wouter
 
Not at all.
 
 
--
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex@attglobal.net
==================
Jerry Stuckle <jstucklex@attglobal.net>: Mar 22 02:25PM -0400

On 3/22/2016 2:08 PM, Mr Flibble wrote:
> Shape base class as presumably all Shapes have these properties.
 
> There is a fundamental rule in OOA/D: prefer composition to inheritance.
 
> /Flibble
 
Incorrect. There is a fundamental rule in OOA/D. Use inheritance where
applicable, and composition where applicable.
 
--
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex@attglobal.net
==================
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Mar 22 06:38PM

On 22/03/2016 18:25, Jerry Stuckle wrote:
 
>> /Flibble
 
> Incorrect. There is a fundamental rule in OOA/D. Use inheritance where
> applicable, and composition where applicable.
 
Of course you use things where applicable however if you can solve a
problem with either inheritance or composition then prefer composition.
 
So we can currently conclude three things about Jerry Stuckle:
 
1) He is a troll;
2) He psychologically projects;
3) He is fractally wrong about most things C++ related.
 
/Flibble
Jerry Stuckle <jstucklex@attglobal.net>: Mar 22 03:56PM -0400

On 3/22/2016 2:38 PM, Mr Flibble wrote:
>> applicable, and composition where applicable.
 
> Of course you use things where applicable however if you can solve a
> problem with either inheritance or composition then prefer composition.
 
Incorrect. They are two different concepts, with two different usages.
You use the one applicable for the situation. There is no "prefer" one
over the other.
 
> 2) He psychologically projects;
> 3) He is fractally wrong about most things C++ related.
 
> /Flibble
 
And we know Mr. Flibble is a troll and a psychology expert. As well as
ignorant as to basic OOAD concepts.
 
 
--
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex@attglobal.net
==================
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Mar 22 08:07PM

On 22/03/2016 19:56, Jerry Stuckle wrote:
 
> Incorrect. They are two different concepts, with two different usages.
> You use the one applicable for the situation. There is no "prefer" one
> over the other.
 
Your fractal wrongness shows no bounds but that is to be expected as
that is the nature of fractal wrongness.
 
/Flibble
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Mar 22 08:19PM

On 22/03/2016 19:56, Jerry Stuckle wrote:
 
> Incorrect. They are two different concepts, with two different usages.
> You use the one applicable for the situation. There is no "prefer" one
> over the other.
 
Incorrect am I?
 
"Composition over inheritance (or Composite Reuse Principle) in
object-oriented programming is the principle that classes should achieve
polymorphic behavior and code reuse by their composition (by containing
instances of other classes that implement the desired functionality)
rather than inheritance from a base or parent class.[2] This is an
often-stated principle of OOP, such as in the influential Design
Patterns: "Favor 'object composition' over 'class inheritance'."[3]"
 
https://en.wikipedia.org/wiki/Composition_over_inheritance
 
Now do what I suggested earlier: read a book and actually learn something.
 
/Flibble
Robert Wessel <robertwessel2@yahoo.com>: Mar 22 12:15AM -0500

On Mon, 21 Mar 2016 12:38:50 -0400 (EDT), bitrex
> synthesis.) So 1 LSB maybe? There will be linear interpolation
> happening as well so it might be good to store the derivative as
> well.
 
 
I'm not quite sure what you mean by one LSB, but if you meant one ULP
(unit in last place) of a float, you'd be OK so long as you did the
computation in a double. In you're converting to an int, you should
be OK doing the initial calculation with doubles as well. My error
estimate was that you'd be looking as something like 200 ULPs worst
case (IOW, of a ~53 bit double, about 45 bits would be correct).
 
If you mean to one ULP of a *double*, life gets much more difficult.
 
 
 
>Input will actually be floats, with a domain between 0 and 1.0 at
> 256 steps. The result will then be shifted and cast to a unit 16
> full with fractional representaton and stored.
 
 
And you're trying to precompute those ~257 values? Something like
this?
 
#include <iostream>
 
#define LIMIT 1000000.
 
constexpr double zexp_w(double x, double x2, double d, double d2)
{
return ((x2/d2)<(1/LIMIT)) ? 0 : (x2/d2 + zexp_w(x, x*x2, d+1,
d2*d));
}
 
constexpr double zexp(double x)
{
return x<0 ? 1/zexp_w(-x, 1, 1, 1) : zexp_w(x, 1, 1, 1);
}
 
inline void test(double x)
{
double t;
t=zexp(x);
std::cout << "e**" << x << " = " << t << std::endl;
}
 
 
#define MAGIC_NUM 6.28
 
constexpr float ff(double x)
{
return MAGIC_NUM*(1-zexp(-3*(x/256)));
}
 
float a[257] =
{
ff(0), ff(1), ff(2), ff(3), ff(4), ff(5), ff(6), ff(7),
ff(8), ff(9),
ff(10), ff(11), ff(12), ff(13), ff(14), ff(15), ff(16), ff(17),
ff(18), ff(19),
ff(20), ff(21), ff(22), ff(23), ff(24), ff(25), ff(26), ff(27),
ff(28), ff(29),
ff(30), ff(31), ff(32), ff(33), ff(34), ff(35), ff(36), ff(37),
ff(38), ff(39),
ff(40), ff(41), ff(42), ff(43), ff(44), ff(45), ff(46), ff(47),
ff(48), ff(49),
ff(50), ff(51), ff(52), ff(53), ff(54), ff(55), ff(56), ff(57),
ff(58), ff(59),
ff(60), ff(61), ff(62), ff(63), ff(64), ff(65), ff(66), ff(67),
ff(68), ff(69),
ff(70), ff(71), ff(72), ff(73), ff(74), ff(75), ff(76), ff(77),
ff(78), ff(79),
ff(80), ff(81), ff(82), ff(83), ff(84), ff(85), ff(86), ff(87),
ff(88), ff(89),
ff(90), ff(91), ff(92), ff(93), ff(94), ff(95), ff(96), ff(97),
ff(98), ff(99),

 
ff(100),ff(101),ff(102),ff(103),ff(104),ff(105),ff(106),ff(107),ff(108),ff(109),
 
ff(110),ff(111),ff(112),ff(113),ff(114),ff(115),ff(116),ff(117),ff(118),ff(119),
 
ff(120),ff(121),ff(122),ff(123),ff(124),ff(125),ff(126),ff(127),ff(128),ff(129),
 
ff(130),ff(131),ff(132),ff(133),ff(134),ff(135),ff(136),ff(137),ff(138),ff(139),
 
ff(140),ff(141),ff(142),ff(143),ff(144),ff(145),ff(146),ff(147),ff(148),ff(149),
 
ff(150),ff(151),ff(152),ff(153),ff(154),ff(155),ff(156),ff(157),ff(158),ff(159),
 
ff(160),ff(161),ff(162),ff(163),ff(164),ff(165),ff(166),ff(167),ff(168),ff(169),
 
ff(170),ff(171),ff(172),ff(173),ff(174),ff(175),ff(176),ff(177),ff(178),ff(179),
 
ff(180),ff(181),ff(182),ff(183),ff(184),ff(185),ff(186),ff(187),ff(188),ff(189),
 
ff(190),ff(191),ff(192),ff(193),ff(194),ff(195),ff(196),ff(197),ff(198),ff(199),
 
 
ff(200),ff(201),ff(202),ff(203),ff(204),ff(205),ff(206),ff(207),ff(208),ff(209),
 
ff(210),ff(211),ff(212),ff(213),ff(214),ff(215),ff(216),ff(217),ff(218),ff(219),
 
ff(220),ff(221),ff(222),ff(223),ff(224),ff(225),ff(226),ff(227),ff(228),ff(229),
 
ff(230),ff(231),ff(232),ff(233),ff(234),ff(235),ff(236),ff(237),ff(238),ff(239),
 
ff(240),ff(241),ff(242),ff(243),ff(244),ff(245),ff(246),ff(247),ff(248),ff(249),
ff(250),ff(251),ff(252),ff(253),ff(254),ff(255),ff(256)
};

int main(void)
{
int i;
 
test(0);
test(1);
test(1.5);
test(2);
test(3.14);
test(42);
test(-1);
test(-3.14);
test(19.4);
 
for (i=0; i<257; i++)
std::cout << MAGIC_NUM << "*(1-e**(" << (-3*(i/256.)) << ") = "
<< a[i] << std::endl;
}
 
 
(Again, you'll need to generate LIMIT better.)
 
 
Output:
 
e**0 = 1
e**1 = 2.71828
e**1.5 = 4.48169
e**2 = 7.38906
e**3.14 = 23.1039
e**42 = 1.73927e+18
e**-1 = 0.367879
e**-3.14 = 0.0432828
e**19.4 = 2.66264e+08
6.28*(1-e**(-0) = 0
6.28*(1-e**(-0.0117188) = 0.0731626
6.28*(1-e**(-0.0234375) = 0.145476
6.28*(1-e**(-0.0351563) = 0.216945
6.28*(1-e**(-0.046875) = 0.287581
6.28*(1-e**(-0.0585938) = 0.357393
6.28*(1-e**(-0.0703125) = 0.426396
6.28*(1-e**(-0.0820313) = 0.494593
6.28*(1-e**(-0.09375) = 0.561995
6.28*(1-e**(-0.105469) = 0.628611
6.28*(1-e**(-0.117188) = 0.694451
...
6.28*(1-e**(-2.87109) = 5.92432
6.28*(1-e**(-2.88281) = 5.92846
6.28*(1-e**(-2.89453) = 5.93256
6.28*(1-e**(-2.90625) = 5.93661
6.28*(1-e**(-2.91797) = 5.94061
6.28*(1-e**(-2.92969) = 5.94456
6.28*(1-e**(-2.94141) = 5.94847
6.28*(1-e**(-2.95313) = 5.95233
6.28*(1-e**(-2.96484) = 5.95615
6.28*(1-e**(-2.97656) = 5.95992
6.28*(1-e**(-2.98828) = 5.96365
6.28*(1-e**(-3) = 5.96734
bitrex <bitrex@de.lete.earthlink.net>: Mar 22 10:47AM -0400

On 03/22/2016 01:15 AM, Robert Wessel wrote:
> estimate was that you'd be looking as something like 200 ULPs worst
> case (IOW, of a ~53 bit double, about 45 bits would be correct).
 
> If you mean to one ULP of a *double*, life gets much more difficult.
 
Yes, I believe that's what I meant, sorry I wasn't more clear. My main
gig is electronics/hardware, I'm still learning to code (but hopefully
getting better all the time.)
 
I don't believe I have the "double" type available for this
processor/codebase, everything I've seen in the libraries that I'm
working with uses single-precision "float."
 
> << a[i] << std::endl;
> }
 
> (Again, you'll need to generate LIMIT better.)
 
Yeah! That's the ticket.
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page.
To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com.

No comments: