Saturday, September 17, 2022

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

wij <wyniijj2@gmail.com>: Sep 17 05:46AM -0700

I did not update my C++ understanding (probable since C++11) to find out I
cannot understand what the codes are about !!!
 
--- frorm https://groups.google.com/g/comp.lang.c++/c/2ebc6ifoPr4
#include <iostream>
#include <utility>
 
using namespace std;
 
int main()
{
auto pow = []<unsigned P>( double b, integral_constant<unsigned, P> )
-> double
{
auto unroll = [&]<size_t ... Indices>( index_sequence<Indices ...> )
-> double
{
return ((Indices, b) * ...);
};
if constexpr( P )
return unroll( make_index_sequence<P>() );
else
return b;
};
cout << pow( 2.0, integral_constant<unsigned, 10'000>() ) << endl;
}
------
 
Question1: What would the code look like if using C++2006 for the above 'program'?
Question2: What is the good of such way of coding?
Bonita Montero <Bonita.Montero@gmail.com>: Sep 17 03:03PM +0200

Am 17.09.2022 um 14:46 schrieb wij:
> }
> ------
 
> Question1: What would the code look like if using C++2006 for the above 'program'?
 
It's not possible to write that before C++20.
 
Bonita Montero <Bonita.Montero@gmail.com>: Sep 17 03:23PM +0200

The code in my initial posting just was some kind of compiler killer
code since the index-sequence resulted in a row of 10,000 size_t's.
But you could write that all smarter like that:
 
#include <iostream>
#include <utility>
 
using namespace std;
 
int main()
{
auto pow = []<unsigned P>( double b, integral_constant<unsigned, P> )
-> double
{
if constexpr( P )
{
double r = 1.0;
[&]<size_t ... Indices>( index_sequence<Indices ...> ) constexpr
{
((r *= P >> Indices & 1 ? b : 1.0, b *= b), ...);
}( make_index_sequence<sizeof(unsigned) * 8>() );
return r;
}
else
return b;
};
cout << pow( 2.0, integral_constant<unsigned, 10>() ) << endl;
}
Bonita Montero <Bonita.Montero@gmail.com>: Sep 17 03:38PM +0200

Am 17.09.2022 um 15:23 schrieb Bonita Montero:
>         }
>         else
>             return b;
return 1.0;
Andreas Kempe <kempe@lysator.liu.se>: Sep 17 02:37PM

> }
> ------
 
> Question1: What would the code look like if using C++2006 for the above 'program'?
 
As was pointed out, you can't really write that code without variadic
templates. What is does at it's core, if I'm not mistaken, is expanding
 
((Indices, b) * ...)
 
to
 
(0, 2.0) * (1, 2.0) * (2, 2.0) * ... * (9999, 2.0)
 
using modern template magic. The comma operator makes the first index
value disappear and we get
 
2.0 * 2.0 * 2.0 * ...
 
10000 times. Writing something that solves the same problem with a loop
could be
 
double result = 1;
for (size_t i = 0; i < 10000; i++)
result *= (i, 2.0);
 
> Question2: What is the good of such way of coding?
 
I personally don't know. I have still to see an example of a variadic
template application that I think makes sense and makes the code more
readable.
Bonita Montero <Bonita.Montero@gmail.com>: Sep 17 04:40PM +0200

Am 17.09.2022 um 16:37 schrieb Andreas Kempe:
 
> I personally don't know. I have still to see an example of a variadic
> template application that I think makes sense and makes the code more
> readable.
 
container.emplace*( ... ) is a good example.
Muttley@dastardlyhq.com: Sep 17 02:50PM

On Sat, 17 Sep 2022 15:03:25 +0200
 
>> Question1: What would the code look like if using C++2006 for the above
>'program'?
 
>It's not possible to write that before C++20.
 
Really? So it outputs some special assembler reserved for C++20 does it?
Muttley@dastardlyhq.com: Sep 17 02:52PM

On Sat, 17 Sep 2022 05:46:57 -0700 (PDT)
 
>Question1: What would the code look like if using C++2006 for the above
>'program'?
>Question2: What is the good of such way of coding?
 
Showing off. He's constantly posting convoluted code to this group desperate
for someone to say "Wow, impressive, you're so clever!"
Bonita Montero <Bonita.Montero@gmail.com>: Sep 17 05:31PM +0200

>> 'program'?
 
>> It's not possible to write that before C++20.
 
> Really? So it outputs some special assembler reserved for C++20 does it?
 
No, you can't unroll variable.
Bonita Montero <Bonita.Montero@gmail.com>: Sep 17 05:32PM +0200

>> Question2: What is the good of such way of coding?
 
> Showing off. He's constantly posting convoluted code to this group desperate
> for someone to say "Wow, impressive, you're so clever!"
 
I don't wanted to show sth. impressive but I wanted to make
others to compile that.
Muttley@dastardlyhq.com: Sep 17 03:59PM

On Sat, 17 Sep 2022 17:31:19 +0200
 
>>> It's not possible to write that before C++20.
 
>> Really? So it outputs some special assembler reserved for C++20 does it?
 
>No, you can't unroll variable.
 
I'm pretty sure the same functionality could be achieved in older C++ or
even C albeit with more lines of code.
Bonita Montero <Bonita.Montero@gmail.com>: Sep 17 06:03PM +0200


>> No, you can't unroll variable.
 
> I'm pretty sure the same functionality could be achieved in older C++ or
> even C albeit with more lines of code.
 
Show me.
Muttley@dastardlyhq.com: Sep 17 04:13PM

On Sat, 17 Sep 2022 18:03:37 +0200
 
>> I'm pretty sure the same functionality could be achieved in older C++ or
>> even C albeit with more lines of code.
 
>Show me.
 
I don't have a c++ 20 compiler so I can't see what it does and I have better
things to do on a saturday than run it in my head.
Bonita Montero <Bonita.Montero@gmail.com>: Sep 17 06:34PM +0200


>> Show me.
 
> I don't have a c++ 20 compiler so I can't see what it does and I have better
> things to do on a saturday than run it in my head.
 
Without C++20 you would have to unroll the fold expressions
N times, in this case 10.000 times. Have fun !
"Alf P. Steinbach" <alf.p.steinbach@gmail.com>: Sep 17 07:55PM +0200

On 17 Sept 2022 18:34, Bonita Montero wrote:
>> things to do on a saturday than run it in my head.
 
> Without C++20 you would have to unroll the fold expressions
> N times, in this case 10.000 times. Have fun !
 
The Boost preprocessor library comes to mind.
 
 
- Alf
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Sep 17 12:03PM -0700

On 9/17/2022 10:55 AM, Alf P. Steinbach wrote:
 
>> Without C++20 you would have to unroll the fold expressions
>> N times, in this case 10.000 times. Have fun !
 
> The Boost preprocessor library comes to mind.
 
Iirc Boost preprocessor is based on the Chaos preprocessor codebase,
right? Anyway, check out this loop unrolling in C for a HMAC lib:
 
https://github.com/ogay/hmac/blob/master/sha2.c
 
Macros indeed. Search the code for UNROLL_LOOPS :^)
Andreas Kempe <kempe@lysator.liu.se>: Sep 17 08:52PM

>> template application that I think makes sense and makes the code more
>> readable.
 
> container.emplace*( ... ) is a good example.
 
Ah, I didn't really consider emplace.
 
Even though I use it myself and do see the advantage of constructing
elements in-place in a container to avoid a move, I'm not too sure I
really find it an improvement when it comes to readability.
Personally, I find vector.push_back(MyType(arg1, arg2)) clearer when
reading code. With emplace, I have to jump to the container
declaration to find what type is being put into it.
 
As for the implementation of emplace itself, I can of course not say
much regarding variadic templates affecting the readability since I
see no way of implementing the function without them.
Mr Flibble <flibble@reddwarf.jmc.corp>: Sep 17 10:18PM +0100

On Sat, 17 Sep 2022 20:52:05 -0000 (UTC)
 
> As for the implementation of emplace itself, I can of course not say
> much regarding variadic templates affecting the readability since I
> see no way of implementing the function without them.
 
Not all types can efficiently move (i.e. move is a copy) or they are
not even copyable ergo the rationale for emplace.
 
/Flibble
Mr Flibble <flibble@reddwarf.jmc.corp>: Sep 17 10:21PM +0100

On Sat, 17 Sep 2022 22:18:34 +0100
 
> Not all types can efficiently move (i.e. move is a copy) or they are
> not even copyable ergo the rationale for emplace.
 
> /Flibble
 
To be fair I was talking about containers in general, as far as vector
is concerned the value_type does need to be at least copyable.
 
/Flibble
Andreas Kempe <kempe@lysator.liu.se>: Sep 17 02:52PM


>> Thank you for an informative reply!
 
>>> [...]
 
> What is a PIC ?
 
A Wikipedia link has been provided, but I think it courteous to
explain what I meant here on Usenet. I was referring to
microcontrollers made by Microchip that range from small 8 bit RISC
processors to larger 32 bit MIPS dittos.
 
Compiling C, or C++ for that matter, for the smaller 8 bit ones is
quite interesting since they don't have a stack on which to push and
pop values. The stack is an automatically managed fix-depth callstack
only and the chip automatically pushes and pops return addresses when
calling and returning from functions.
 
I enjoy the smaller 8 bit PICs for their small instruction set where
all instructions except for branching take the same amount of time,
making timing code pretty easy to write. The bad thing is that there
is, to my knowledge, no good open source compiler, although the basic
Microchip C compiler is free as in free beer.
 
// Andreas Kempe
Bonita Montero <Bonita.Montero@nospicedham.gmail.com>: Sep 17 04:35PM +0200

I wanted to check if denormal numbers have slower performance on
modern CPUs. Intel introduced the DAZ / FTZ Bits with SSE1 because
denormals were even handled in microcode:
 
#include <iostream>
#include <bit>
#include <cstdint>
#include <chrono>
#include <utility>
#include <atomic>
 
using namespace std;
using namespace chrono;
 
uint64_t denScale( uint64_t rounds, bool den );
 
int main()
{
auto bench = []( bool den ) -> double
{
constexpr uint64_t ROUNDS = 25'000'000;
auto start = high_resolution_clock::now();
int64_t nScale = denScale( ROUNDS, den );
return (double)duration_cast<nanoseconds>(
high_resolution_clock::now() - start ).count() / nScale;
};
double
tDen = bench( true ),
tNorm = bench( false ),
rel = tDen / tNorm - 1;
cout << tDen << endl;
cout << tNorm << endl;
cout << trunc( 100 * 10 * rel + 0.5 ) / 10 << "%" << endl;
}
 
MASM code:
 
PUBLIC ?denScale@@YA_K_K_N@Z
 
CONST SEGMENT
DEN DQ 00008000000000000h
ONE DQ 03FF0000000000000h
P5 DQ 03fe0000000000000h
CONST ENDS
 
_TEXT SEGMENT
?denScale@@YA_K_K_N@Z PROC
xor rax, rax
test rcx, rcx
jz byeBye
mov r8, ONE
mov r9, DEN
test dl, dl
cmovnz r8, r9
movq xmm1, P5
mov rax, rcx
loopThis:
movq xmm0, r8
REPT 52
mulsd xmm0, xmm1
ENDM
sub rcx, 1
jae loopThis
mov rdx, 52
mul rdx
byeBye:
ret
?denScale@@YA_K_K_N@Z ENDP
_TEXT ENDS
END
 
For my PC normal numbers have a 25% higher throughput.
Feel free to post your results also.
Mr Flibble <flibble@reddwarf.jmc.corp>: Sep 17 02:06AM +0100

On Fri, 16 Sep 2022 18:37:03 -0500
 
> > /Flibble
 
> Why are you deliberately cross-posting when follow-up is explicitly
> set of comp.theory?
 
I am deliberately cross-posting to the same newsgroups that you
originally posted to which to me seems entirely appropriate, and I have
done so again; if you don't like it then you shouldn't cross-post in
the first place.
 
> return a value then you must be nuts.
 
> If you can't see that the return value from Hx is unreachable from
> the correctly simulated Px then you must be incompetent.
 
A correct simulation of Px would show that Px halts: your simulation
is incorrect because your halting decider is broken.
 
/Flibble
Mr Flibble <flibble@reddwarf.jmc.corp>: Sep 17 03:22PM +0100

On Fri, 16 Sep 2022 20:10:57 -0500
 
> Since you have been made fully aware that extensive cross-posting to
> these groups can permanently kill these groups you are a spiteful
> jackass.
 
Pointing out your mistakes to your audience isn't being a spiteful
jackass, it is an honourable public service.
 
/Flibble
Bonita Montero <Bonita.Montero@gmail.com>: Sep 17 11:52AM +0200

#include <iostream>
#include <utility>
 
using namespace std;
 
int main()
{
auto pow = []<unsigned P>( double b, integral_constant<unsigned, P> )
-> double
{
auto unroll = [&]<size_t ... Indices>( index_sequence<Indices ...> )
-> double
{
return ((Indices, b) * ...);
};
if constexpr( P )
return unroll( make_index_sequence<P>() );
else
return b;
};
cout << pow( 2.0, integral_constant<unsigned, 10'000>() ) << endl;
}
Bonita Montero <Bonita.Montero@gmail.com>: Sep 17 04:13PM +0200

Am 17.09.2022 um 11:52 schrieb Bonita Montero:
>     };
>     cout << pow( 2.0, integral_constant<unsigned, 10'000>() ) << endl;
> }
 
This was just a joke because the above code is just a compiler-killer
 
| C:\Users\Boni>timep cl -std:c++20 -Ox x.cpp -EHs
| Microsoft (R) C/C++ Optimizing Compiler Version 19.33.31630 for x64
| Copyright (C) Microsoft Corporation. All rights reserved.
|
| x.cpp
| Microsoft (R) Incremental Linker Version 14.33.31630.0
| Copyright (C) Microsoft Corporation. All rights reserved.
|
| /out:x.exe
| x.obj
| real 581305.97ms
| user 580703.12ms
| sys 968.75ms
| cycles 2.089.456.387.776
 
The above result is from a TR3990X Zen2 machine.
Compiling the same code with g++11 on a 1800X
Zen1 machine takes 48 seocnds.
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: