Thursday, March 26, 2020

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

"Öö Tiib" <ootiib@hot.ee>: Mar 25 04:27PM -0700

On Thursday, 26 March 2020 01:20:49 UTC+2, Mike Terry wrote:
> volatile unsigned long long int result1 = fibonacci( 47 );
> volatile time_t endTime1 = time(nullptr);
 
> which seems to work on my system.
 
Yes but OP's problem sounded like reordering I/O and time() call:
 
unsigned long long int result1 = fibonacci( 47 );
cout << "fibonacci( 47 ) = " << result1 << endl; // <- I/O (1)
time_t endTime1 = time(nullptr); // <- time() call (2)
Mike Terry <news.dead.person.stones@darjeeling.plus.com>: Mar 25 11:33PM

On 25/03/2020 23:13, Öö Tiib wrote:
> something volatile or doing input from somewhere so perhaps MS
> optimizer has screwed up tracking of what of its API has side
> effects.
 
I'm just a regular C++ user, and don't understand the relevent standards
as well as others here!
 
It would seem to me that calling time() probably IS deemed as having
side effects by the VC compiler, but this in itself would only prevent
the re-ordering of the calls to time(). I guess the compiler sees that
fibonacci() has no side effects, and so it's free to re-order it with
respect to the time() calls. (?) As a test for OP, deliberately
introducing a side effect into fibonacci() might solve the problem.
 
 
Mike.
"Öö Tiib" <ootiib@hot.ee>: Mar 25 04:49PM -0700

On Thursday, 26 March 2020 01:34:05 UTC+2, Mike Terry wrote:
> fibonacci() has no side effects, and so it's free to re-order it with
> respect to the time() calls. (?) As a test for OP, deliberately
> introducing a side effect into fibonacci() might solve the problem.
 
 
Yes but in OP's code result of fibonzzi() was used in output before
calling time() and that must be as good as assigning to volatile.
 
unsigned long long int result1 = fibonacci( 47 );
cout << "fibonacci( 47 ) = " << result1 << endl;
time_t endTime1 = time(nullptr);
Mike Terry <news.dead.person.stones@darjeeling.plus.com>: Mar 26 12:00AM

On 25/03/2020 23:27, Öö Tiib wrote:
 
> unsigned long long int result1 = fibonacci( 47 );
> cout << "fibonacci( 47 ) = " << result1 << endl; // <- I/O (1)
> time_t endTime1 = time(nullptr); // <- time() call (2)
 
Hmm, this would be consistent with the compiler recognising the time()
calls and cout<< calls as both having side effects (or involving I/O),
but not the fibonacci() call, thus allowing it (supposedly) to move the
fibonacci() call to after the time() call.
 
Here is the OP's code which gives the unexpected result: (I've prefixed
lines with side effects or I/O with # )
 
///// Actual code (unexpected result)
# cout << "Calculating fibonacci( 47 )" << endl;
 
# time_t startTime1 = time( nullptr );
unsigned long long int result1 = fibonacci( 47 );
# time_t endTime1 = time(nullptr);
 
# cout << "fibonacci( 47 ) = " << result1 << endl;
 
..and here is the "optimised" result: (obvious why zero seconds are
recorded)
 
///// Compiler reordere code
# cout << "Calculating fibonacci( 47 )" << endl;
 
# time_t startTime1 = time( nullptr );
# time_t endTime1 = time(nullptr);
 
unsigned long long int result1 = fibonacci( 47 );
# cout << "fibonacci( 47 ) = " << result1 << endl;
 
 
The OP's code which worked as expected is as like this:
 
///// Actual code (giving expected result)
 
# cout << "Calculating fibonacci( 47 )" << endl;
 
# time_t startTime1 = time( nullptr );
unsigned long long int result1 = fibonacci( 47 );
 
# cout << "fibonacci( 47 ) = " << result1 << endl;
# time_t endTime1 = time(nullptr);
 
Here, the second time() call can't be reordered before the fibonacci()
call because:
1) it must occur after the second cout<< call
2) the second cout<< call must occur after the fibonacci() call,
as it uses the result1 variable.
 
Well, we could say that still the compiler could have moved the
fibonacci() call to before the first time() call, rather than after the
second time() call. True - but who knows why it chooses which way to
optimise? (I mean, it's not deliberately trying to thwart the programmer!)
 
 
Mike.
Mike Terry <news.dead.person.stones@darjeeling.plus.com>: Mar 26 12:09AM

On 25/03/2020 23:49, Öö Tiib wrote:
 
> unsigned long long int result1 = fibonacci( 47 );
> cout << "fibonacci( 47 ) = " << result1 << endl;
> time_t endTime1 = time(nullptr);
 
..and this code worked as expected. I doubt that simply using a
variable for output /at a later point of execution/ is considered
equivalent to marking the variable as volatile /from its creation/.
(But now I'm guessing...)
 
Mike.
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Mar 26 12:17AM

On Wed, 25 Mar 2020 16:49:24 -0700 (PDT)
Öö Tiib <ootiib@hot.ee> wrote:
[snip]
 
> unsigned long long int result1 = fibonacci( 47 );
> cout << "fibonacci( 47 ) = " << result1 << endl;
> time_t endTime1 = time(nullptr);
 
§4.6/7 of C++17 says
 
The least requirements on a conforming implementation are:
 
* Accesses through volatile glvalues are evaluated strictly
according to the rules of the abstract machine.
 
* At program termination, all data written into files shall be
identical to one of the possible results that execution of the
program according to the abstract semantics would have produced.
 
* The input and output dynamics of interactive devices shall take
place in such a fashion that prompting output is actually
delivered before a program waits for input. What constitutes an
interactive device is implementation-defined. These collectively
are referred to as the observable behavior of the program.
 
I cannot say I fully understand the consequences, but it seems
reasonably clear that printing the correct value of the 47th (and 46th)
fibonacci to stdout has a computational consequence and must be
correct (within available resource limits), but printing the time at
and during which the program happens to be executed does not, in the
sense that no particular value of time is predicated by the program as
written.
 
So maybe the optimization is permitted. Dunno.
"Öö Tiib" <ootiib@hot.ee>: Mar 25 05:29PM -0700

On Thursday, 26 March 2020 02:00:37 UTC+2, Mike Terry wrote:
> unsigned long long int result1 = fibonacci( 47 );
> # time_t endTime1 = time(nullptr);
 
> # cout << "fibonacci( 47 ) = " << result1 << endl;
 
Nope, for third time OP's code was verbatim:
 
cout << "fibonacci( 47 ) = " << result1 << endl;
time_t endTime1 = time(nullptr); // SEE THIS STATEMENT
 
You have yourself reordered.
 
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Mar 26 12:43AM

On Thu, 26 Mar 2020 00:17:22 +0000
> sense that no particular value of time is predicated by the program as
> written.
 
> So maybe the optimization is permitted. Dunno.
 
And if so, as another poster has observed, making the time values
volatile should deal with the OP's issue.
Mike Terry <news.dead.person.stones@darjeeling.plus.com>: Mar 26 01:24AM

On 26/03/2020 00:29, Öö Tiib wrote:
 
> cout << "fibonacci( 47 ) = " << result1 << endl;
> time_t endTime1 = time(nullptr); // SEE THIS STATEMENT
 
> You have yourself reordered.
 
You're not reading the OP correctly. Yes, I know what he wrote in the
"verbatim" program code.
 
OK, OP starts with the following paragraph explaining what the following
code is, and what the unexpected result is:
 
The code below as is works as expected.
But if I move the statement ending with the
comment "SEE THIS STATEMENT" to before the
previous statement,
it calculates time as 0.000000000 minutes.
 
Note the phrase "works as expected". This indicates that the "verbatim"
code is the code where things run IN THE EXPECTED ORDER.
 
Here is the verbatum code (GIVING EXPECTED RESULT):
 
cout << "Calculating fibonacci( 47 )" << endl;
time_t startTime1 = time( nullptr );
unsigned long long int result1 = fibonacci( 47 );
 
 
cout << "fibonacci( 47 ) = " << result1 << endl;
time_t endTime1 = time(nullptr); // SEE THIS STATEMENT
cout << "Calculation time = "
<< (endTime1 - startTime1 ) / 60.0
<< " minutes\n" << endl;
 
Now note the phrase "But if I move the statement.....[unexpected result]"
 
So, the code with the unexpected result has the time() call moved up AS
I SHOWED IT.
 
SUMMARY: Yes, I've re-ordered the verbatim code AS INSTRUCTED BY OP TO
REPRODUCE THE UNEXPECTED BEHAVIOUR.
 
When explaining the unexpected compiler behaviour there are two code
listings to consider:
 
a) the "actual" code given to the compiler
b) the "reordered" code as adjusted internally by the compiler
 
The code I quote above is the "actual" compiler input GIVING THE
UNEXPECTED RESULT. I follow this (below) by the "compiler reordered" code.
 
The "verbatim" code (which works as expected) I then listed (even
further below), along with an explanation for why it doesn't give
unexpected results.
 
No need to spend any more time on this, as I've already wasted more than
it warrents, and won't respond any further.
 
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Mar 26 04:36AM +0100

On 25.03.2020 22:01, Bob Langelaan wrote:
> return fibonacci( n - 1 ) + fibonacci( n - 2 );
> } // end else
> } // end function fibonacci
 
I've reproduced the issue with Visual C++ 2019, using optimization
option `/O2`. With the `time` call before the output it reports 0 time
even though the code clearly runs for several seconds.
 
I believe that a compiler is permitted to move the call to `time` to
before the call to `fibonacci`, since it can prove that the latter
doesn't change any state that the `time` function could depend on. The
flow of time is not regarded as part of the abstract machine state.
 
Adding `std::atomic_thread_fence(std::memory_order_acq_rel);` around
each `fibonacci` call did not prevent this. I don't know if it should.
But I felt it was worth trying.
 
Adding `volatile` to the result variables fixed it.
 
However, most uses of `volatile` will be deprecated in C++20; <url:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1152r4.html>.
And apparently that includes `volatile` return types. So one cannot,
apparently, quick-fix it by making `time` (and `clock`, etc.) produce
`volatile` values, if that would work, which I don't know.
 
This reminds me of the C++11 (or was it C++14) /carte blanche/ to
completely optimize away a provably infinite loop.
 
A very impractical effect for real programming, stemming from the
standard specifying things in terms of a too limited academic ivory
tower abstraction.
 
- Alf
"Öö Tiib" <ootiib@hot.ee>: Mar 25 11:58PM -0700

On Thursday, 26 March 2020 03:24:29 UTC+2, Mike Terry wrote:
> I SHOWED IT.
 
> SUMMARY: Yes, I've re-ordered the verbatim code AS INSTRUCTED BY OP TO
> REPRODUCE THE UNEXPECTED BEHAVIOUR.
 
OK. Seems that I misunderstood that part. On that case your solution
of using volatile is fine.
Unless they have done something bad (as they seem to plan) to volatile.
"Öö Tiib" <ootiib@hot.ee>: Mar 26 01:30AM -0700

On Thursday, 26 March 2020 05:36:57 UTC+2, Alf P. Steinbach wrote:
 
> A very impractical effect for real programming, stemming from the
> standard specifying things in terms of a too limited academic ivory
> tower abstraction.
 
Precisely! Idea of breaking volatile seems to come from same school as
that infinite loop mess. Making low level hardware drivers impossible
to write in C++ would result with developers being forced to use low
level hardware drivers of hardware vendors and making it impossible
for smaller hardware vendors to write their drivers in anything but
assembler (that is rare and expensive skill these days).
David Brown <david.brown@hesbynett.no>: Mar 26 11:32AM +0100

On 26/03/2020 00:13, Öö Tiib wrote:
> something volatile or doing input from somewhere so perhaps MS
> optimizer has screwed up tracking of what of its API has side
> effects.
 
The compiler can't re-order things with side-effects. But calculating
fibonacci() does not have any side-effects, and the compiler can
re-arrange that with respect to any side-effect code. There is a common
misunderstanding that code observable behaviour (or potentially having
observable behaviour) also forces an order on other code - it does not.
David Brown <david.brown@hesbynett.no>: Mar 26 11:40AM +0100

On 26/03/2020 01:17, Chris Vine wrote:
> sense that no particular value of time is predicated by the program as
> written.
 
> So maybe the optimization is permitted. Dunno.
 
When the code is:
 
unsigned long long int result1 = fibonacci( 47 );
cout << "fibonacci( 47 ) = " << result1 << endl;
time_t endTime1 = time(nullptr);
 
the compiler needs to write the output before measuring the time. And
in order to write the output, it must calculate the result of the fibonacci.
 
 
When the code is:
 
unsigned long long int result1 = fibonacci( 47 );
time_t endTime1 = time(nullptr);
cout << "fibonacci( 47 ) = " << result1 << endl;
 
the compiler must measure the time before writing out the result. And
in order to write the output, it must calculate the result of the fibonacci.
 
But it does /not/ need the result of the fibonacci in order to measure
the time. The compiler can see that calling fibonacci(47) cannot
possibly have side-effects that are relevant to the call to time().
Therefore it is fine to delay the calculation until the results are needed.
 
Thus this optimisation is perfectly valid.
 
The simple solution here is to use volatile:
 
volatile unsigned long long int result1 = fibonacci( 47 );
time_t endTime1 = time(nullptr);
cout << "fibonacci( 47 ) = " << result1 << endl;
 
This forces the compiler to calculate the results and write result1
before getting the time.
 
I'd also recommend the "47" be replaced by a volatile:
 
volatile const unsigned int N = 47;
volatile unsigned long long int result1 = fibonacci(N);
time_t endTime1 = time(nullptr);
cout << "fibonacci( 47 ) = " << result1 << endl;
 
A smart enough compiler could see that fibonacci(47) can be
pre-calculated at compile time, and eliminate the run-time calculation
entirely. A less smart one might eliminate some of it, but not all.
David Brown <david.brown@hesbynett.no>: Mar 26 11:58AM +0100

On 26/03/2020 09:30, Öö Tiib wrote:
> level hardware drivers of hardware vendors and making it impossible
> for smaller hardware vendors to write their drivers in anything but
> assembler (that is rare and expensive skill these days).
 
No, you are both misunderstanding this quite significantly.
 
The re-ordering of the calculation in this code is allowed because the
calculation of fibonacci(47) has no observable behaviour. Adding a
memory fence around it will not force any order, because "result1" is
not required to be in memory - though a compiler is certainly free to
interpret the fence more generally and use it for ordering result1.
 
Making result1 volatile /will/ force the desired order.
 
Making the return type of functions like "time" volatile is just a silly
idea. It makes no sense at all. Think about what volatile means, and
it should be obvious.
 
No version of C or C++ has a /carte blanche/ to remove infinite loops.
Quoting from C11 (because I have it open at the moment):
 
"""
An iteration statement whose controlling expression is not a constant
expression, 156) that performs no input/output operations, does not
access volatile objects, and performs no synchronization or atomic
operations in its body, controlling expression, or (in the case of a for
statement) its expression-3, may be assumed by the implementation to
terminate. 157)
"""
 
In C++, this is part of the "forward progress guarantee", and amounts to
the same thing. An infinite loop that does nothing is undefined
behaviour - an infinite loop that does something observable is fine.
 
 
And as for the suggested changes to "volatile", the recommendation is to
disallow complicated cases and only allow simple ones. That is /fine/ -
the complicated cases should never be used in the first place.
 
So if you have:
 
volatile int a, b, c;
 
then
a = 1;
b = c;
 
and the like are still allowed. You can have pointers-to-volatile, you
can read and write volatile data, you can use pointer casts to make a
"use a volatile access here" expressions (which every compiler has
allowed, but was not defined behaviour until C18).
 
What you can't do are things like:
 
a = b++ + c++;
 
That's fine. There is no standard for saying how these things should
work, and compilers interpret then in very different ways.
 
If your low-level drivers are affected by the new restrictions in
volatile, then they /should/ be re-written - even if you are using older
C++ standards.
Melzzzzz <Melzzzzz@zzzzz.com>: Mar 26 08:21AM


> I only ever call "join" without checking that it's 'joinable' beforehand (even if I know that the thread entry point function might have returned).
 
> Even if you do check that it's joinable first, it might not be joinable a few microseconds later when you try to join it.
 
> Can't we just simply call "join"?
 
No. joining on detached thread is UB.
 
 
--
press any key to continue or any other to quit...
U ničemu ja ne uživam kao u svom statusu INVALIDA -- Zli Zec
Svi smo svedoci - oko 3 godine intenzivne propagande je dovoljno da jedan narod poludi -- Zli Zec
Na divljem zapadu i nije bilo tako puno nasilja, upravo zato jer su svi
bili naoruzani. -- Mladen Gogala
"Öö Tiib" <ootiib@hot.ee>: Mar 26 01:37AM -0700

On Thursday, 26 March 2020 10:21:45 UTC+2, Melzzzzz wrote:
 
> > Even if you do check that it's joinable first, it might not be joinable a few microseconds later when you try to join it.
 
> > Can't we just simply call "join"?
 
> No. joining on detached thread is UB.
 
AFAIK it throws on non-joinable thread (not UB) and uncaught exception
(is also not UB but) just has often undesirable result.
Melzzzzz <Melzzzzz@zzzzz.com>: Mar 26 08:39AM


>> No. joining on detached thread is UB.
 
> AFAIK it throws on non-joinable thread (not UB) and uncaught exception
> (is also not UB but) just has often undesirable result.
Well, I use pthreads, I concluded from there ;)
 
--
press any key to continue or any other to quit...
U ničemu ja ne uživam kao u svom statusu INVALIDA -- Zli Zec
Svi smo svedoci - oko 3 godine intenzivne propagande je dovoljno da jedan narod poludi -- Zli Zec
Na divljem zapadu i nije bilo tako puno nasilja, upravo zato jer su svi
bili naoruzani. -- Mladen Gogala
Frederick Gotham <cauldwell.thomas@gmail.com>: Mar 26 12:53AM -0700

Jorgen Grahn wrote:
 
> native language? For the combination C++ / Sweden, I have never seen
> it: code is IME always in English, at work and at university.
> (But I admit we are fairly extreme in that area.)
 
Christian Gollwitzer wrote:
> You probably overthink this. Technical papers are usually published
> exclusively in English, especially if they ar ein the field of computer
> science (and most other fields, too).
 
 
Even if 99% of people don't bother having their paper translated into other languages, I shall.
 
 
Vir Campestris wrote:
> I've never known a software engineer who can't read
> English with a reasonable level of proficiency.
 
 
I want beginner programmers and cryptographers to be able to read my paper in a language they understand (instead of running it through Google Translate). And also there might be a proficient programmer, cryptographer or mathematician who isn't good with languages -- I have a friend who's a high school math teacher and he's not good with languages.
woodbrian77@gmail.com: Mar 25 10:08PM -0700

Shalom
 
Are people rethinking on-line code generation now
that the cat is out of the bag with the Wuhan virus?
https://github.com/Ebenezer-group/onwards
 
 
"There is a time for everything, and a season for every
activity under the heavens:
a time to be born and a time to die,
a time to plant and a time to uproot,
a time to kill and a time to heal,
a time to tear down and a time to build,
a time to weep and a time to laugh,
a time to mourn and a time to dance,
a time to scatter stones and a time to gather them,
 
a time to embrace and a time to refrain from embracing,
 
a time to search and a time to give up,
a time to keep and a time to throw away,
a time to tear and a time to mend,
a time to be silent and a time to speak,
a time to love and a time to hate,
a time for war and a time for peace."
Ecclesiastes 3
 
And if anyone has suggestions on how to improve my
software, please let me know. Thanks in advance.
 
 
Brian
Ebenezer Enterprises - Enjoying programming again.
http://webEbenezer.net
Christian Gollwitzer <auriocus@gmx.de>: Mar 26 07:33AM +0100

> Are people rethinking on-line code generation now
> that the cat is out of the bag with the Wuhan virus?
 
No. This incident has no influence on the other thing. It's magical
thinking that unconnected events can influence each other. This lead
former people to believe in werid things like witchcraft or other
supernatural powers.
 
Christian
Jorgen Grahn <grahn+nntp@snipabacken.se>: Mar 26 06:44AM

On Thu, 2020-03-26, Christian Gollwitzer wrote:
>> Are people rethinking on-line code generation now
>> that the cat is out of the bag with the Wuhan virus?
 
> No. This incident has no influence on the other thing.
 
It would have been different in the 1970s I suppose, when we would
have gone to the data central with our stack of punched cards ...
 
/Jorgen
 
--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
"Öö Tiib" <ootiib@hot.ee>: Mar 25 11:46PM -0700

> Shalom
 
> Are people rethinking on-line code generation now
> that the cat is out of the bag with the Wuhan virus?
 
No, the off-line code generators of Protocol Buffers, Thrift,
Apache Avro, FlatBuffers and others do not help to spread the
virus in any way so those won't be banned.
Ian Collins <ian-news@hotmail.com>: Mar 26 08:33PM +1300

> Shalom
 
> Are people rethinking on-line code generation now
> that the cat is out of the bag with the Wuhan virus?
 
It's Covid-19 and no. Twat.
 
--
Ian.
Sam <sam@email-scan.com>: Mar 25 08:01PM -0400

Chris Vine writes:
 
> "But nobody can offend me without my permission, first. And I do not
> give anyone permission to offend me" is nothing more than a
> projection. Bullies don't like it when people hit back.
 
If you'd like to complete your compilation of my favorite sayings, just let
me know and I'll put together a list.
 
> time ago, in a galaxy far, far away. But not everyone is as smart as
> me... I think we're looking at a future Microsoft Windows developer,
> here".
 
Well, you got me there, because I can't return the favor: I have absolutely
no idea what you said, or wrote, last year. Even last month, come to think
of it. Whatever it was, it could not have been memorable enough to have such
a profound effect on me that I would still remember it, years later, unlike
my proclamations which make such a lasting impact on you, from the looks of
it.
 
> When told he was a dickhead he didn't like it at all. His reaction
> to having the facts pointed out to him was quite satisfying.
 
Can you refresh my memory as to how exactly you reached your conclusion that
I "didn't like it at all"? You are shirley mistaken about it; and for the
same exact reasons that I just explained, of course, in painful detail. It
is logically impossible for me to have any reaction to being called a
dickhead, since this presumes that I would care.
 
A comp.lang.c++ search for "Chris Vine dickhead" finds two posts, the one
that you just made, and one from 2017. A search for "Sam dickhead" finds
only your, sole, post, from three hours ago.
 
Your other post, from 2017, reads:
 
# And we now also seem to have acquired this Jeff guy who cross-posts
# random garbage to this newsgroup in classic troll mode. And we have a
# different poster (strangely silent for the last 4 or so weeks) who will
# join any argument which he doesn't understand and take it to the point
# of absurdity, cannot bear not to have the last word and doesn't mind
# projecting himself as a complete dickhead.
 
Was that in referring to me? The fact that I may post occasionally, or in
bursts, is nowhere close to being notable. Examining your own posting
frequency also finds a fairly similar, in-the-ballpark, posting pattern.
Maybe that's because somsone called /you/ a dickhead, perhaps?
 
But, in any case, I'm genuinely curious to find out who called me a
dickhead, years ago, an event that must've left a bigger impression on you,
than on me, since I can't even remember it. But you do, apparently, so I'm
waiting to hear the details.
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: