Sunday, October 10, 2021

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

Bonita Montero <Bonita.Montero@gmail.com>: Oct 10 06:51PM +0200

I derived two hash-algorithms from FNV32/64 and CRC64 that don't yield
the same results, and don't provide the opportunity for error-correction
for CRC, but which have the same equal distribution and are much more
performant on modern OoO-CPUS. How did I do that ?
 
These are the results on my Linux Ryzen 7 1800X:
 
fnv streamed 32: : 0.964425 GB/s
fnv blocked 32: : 1.96624 GB/s 104%
fnv streamed 64: : 0.939418 GB/s
fnv blocked 64: : 3.11791 GB/s 232%
crc64: : 0.478093 GB/s
crc64 blocked: : 2.39144 GB/s 400%
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Oct 10 12:36PM -0700

On 10/10/2021 9:51 AM, Bonita Montero wrote:
> the same results, and don't provide the opportunity for error-correction
> for CRC, but which have the same equal distribution and are much more
> performant on modern OoO-CPUS. How did I do that ?
 
I don't know.
 
 
> fnv blocked 64:  : 3.11791 GB/s 232%
> crc64:           : 0.478093 GB/s
> crc64 blocked:   : 2.39144 GB/s 400%
 
Btw, if you can come up with a really fast SHA2 impl, I would be
interested because of my experimental HMAC cipher. I have a C version:
 
https://groups.google.com/g/comp.lang.c/c/a53VxN8cwkY/m/XKl1-0a8DAAJ
 
https://pastebin.com/raw/feUnA3kP
 
Also, I put it up online using a rather inefficient, but working SHA2
lib. I say inefficient because it does not provide an update method.
 
http://fractallife247.com/test/hmac_cipher/ver_0_0_0_1?ct_hmac_cipher=0422a78fffa58f349a486b3842d2eedfa87985658fb9f011153b896fb97b4b291224ddd327017e9fcdf4b3d8fd5dfde47ae8f23639044f7c5c73a1f0a891087814a139dfe44e47b4300cac921f736776ab7042fb09aae38f8780aa49e5cd128d141e2982d3aa4b288fceef939126c0a319da20b0cf219732504491eb14c691149f
scott@slp53.sl.home (Scott Lurndal): Oct 10 10:51PM


>Btw, if you can come up with a really fast SHA2 impl, I would be
>interested because of my experimental HMAC cipher. I have a C version:
 
https://en.wikipedia.org/wiki/Intel_SHA_extensions
https://developer.arm.com/documentation/100076/0100/a64-instruction-set-reference/a64-cryptographic-algorithms/a64-cryptographic-instructions?lang=en
Steve Keller <keller.steve@gmx.de>: Oct 10 08:28AM +0200


> Const objects have internal linkage unless it is specified with
> "extern". I think it's in 6.2.1 in C++17, but I won't swear to it.
 
I thought I havd already used this like in C and it worked. But I'm
obviously wrong since I tested with very old GNU C++ compiler and it
also shows this behavior.
 
But I wonder why C++ differs here from C when C already has 'static'
for this purpose. And why treat const and non-const so differently?
It means you have to use 'static' to make a non-const object internal
and 'extern' to make a const object external.
 
Steve
Steve Keller <keller.steve@gmx.de>: Oct 10 08:55AM +0200


> const int a = 42;
 
> which would function almost exactly like a #define, plus it honors C++
> namespaces and cannot be undefined.
 
If you write such "global" const objects into a header file they are
in fact not global, because the implicit 'static' makes them local to
file translation unit and this can even cause duplication:
 
$ cat foo.hh
const int a = 42;

const int *bar();
$ cat x.cc
#include "foo.hh"

const int *bar() { return &a; }
$ cat y.cc
#include <iostream>

#include "foo.hh"

const int *foo() { return &a; }

int main()
{
std::cout << (void *)foo() << '\n' << (void *)bar() << '\n';
}
$ g++ -Os -o foo x.cc y.cc
$ ./foo
0x56027d731008
0x56027d731004
 
For a small 'int' one may not care but for larger constant objects
this may be really bad.
 
To avoid it, I think you still have to write the defintion into only
one C++ source file using 'extern'
 
extern const int = 42;
 
and put
 
extern const int a;
 
into the header file. I still don't see the advantage for C++ to
differ from C here.
 
 
Steve
Bo Persson <bo@bo-persson.se>: Oct 10 10:34AM +0200

On 2021-10-10 at 08:55, Steve Keller wrote:
> 0x56027d731004
 
> For a small 'int' one may not care but for larger constant objects
> this may be really bad.
 
It only causes duplication if you take the address and return a pointer.
Why do that for a constant defined in a header?
Paavo Helde <myfirstname@osa.pri.ee>: Oct 10 12:03PM +0300

10.10.2021 09:28 Steve Keller kirjutas:
> for this purpose. And why treat const and non-const so differently?
> It means you have to use 'static' to make a non-const object internal
> and 'extern' to make a const object external.
 
Global objects have pretty limited use in C++, because of the "Static
Initialization Order Fiasco". As soon as one such global object in one
translation unit starts to depend on another global object in another
translation unit, you cannot be sure any more they are constructed in
the right order.
 
In C++ this is a bigger problem than in C as C++ relies heavily on
constructors whose code would run before main() for global objects.
 
In practice, one typically hides global non-const objects away as a
static object inside some function, or at least accessed only via
functions in a single TU, which makes the object creation order much
better controlled.
 
Const global objects are TU-specific by default, so the problem does not
occur. As soon as you make them extern, the danger of the initialization
fiasco appears, even for something so simple as an int.
Paavo Helde <myfirstname@osa.pri.ee>: Oct 10 12:14PM +0300

10.10.2021 09:55 Steve Keller kirjutas:
> 0x56027d731004
 
> For a small 'int' one may not care but for larger constant objects
> this may be really bad.
 
The unused const objects are routinely optimized away be the compiler,
as you saw by yourself ("object file was empty").
 
It's true that for larger and more complicated objects this might not
work so well. So don't do that. Put the object in a single TU and
provide functions to access it. (Making the object extern is not safe in
general because of the "Static Initialization Order Fiasco".)
 
 
> extern const int a;
 
> into the header file. I still don't see the advantage for C++ to
> differ from C here.
 
In some sense the do not differ. The const globals in C++ are primarily
meant for replacing C #define. Each C #define is TU-specific and gets
fully preprocessed by the preprocessor, no other TU-s are involved.
David Brown <david.brown@hesbynett.no>: Oct 10 12:29PM +0200

On 10/10/2021 08:28, Steve Keller wrote:
> It means you have to use 'static' to make a non-const object internal
> and 'extern' to make a const object external.
 
> Steve
 
I think this goes back to early history (and I hope and expect to be
corrected if I've got it wrong). "const" was first part of C++, before
being copied over to C. So when it was introduced in C++ there was no
conflicting version in C. Since one of the ideas behind it was to get a
better alternative to #define constants, it was important to be
convenient in headers, and that for common usage such as integer
constants, it could be as efficient - there was no need to make the
constant an actual allocated object in memory. Add to that, the idea of
objects and identifiers being of external linkage by default is a
/major/ design mistake in C (IMHO, of course). It is far better to have
things with internal linkage unless you /really/ want to make them
available in other units. Perhaps making "const" objects "static" by
default was seen as a step to correct this.
 
So the question is why C didn't copy that aspect when they copied
"const". I guess they thought it was simpler and more consistent to
have the same rules for const objects as for non-const objects.
 
In headers, I tend to be explicit about using "static" or "extern", even
when it might not be necessary - I prefer explicit and it's not uncommon
for a header to be usable from both C and C++.
David Brown <david.brown@hesbynett.no>: Oct 10 12:33PM +0200

On 10/10/2021 08:55, Steve Keller wrote:
 
> To avoid it, I think you still have to write the defintion into only
> one C++ source file using 'extern'
 
> extern const int = 42;
 
You don't (IMHO) want "extern" here - you want to make sure that this
file includes the header with the "extern const int a;" declaration.
(And you forgot the "a" in that line.)
 
 
> extern const int a;
 
> into the header file. I still don't see the advantage for C++ to
> differ from C here.
 
It is convenient when you have const objects defined within a file and
that are local to the file - there is no need for a "static". (A lot of
people are far too lazy about putting "static" where it is appropriate
in their C and C++ coding.)
 
With C++17, you can also write:
 
extern inline const int a = 42;
 
in the header, and you don't need a definition in a C++ file.
Steve Keller <keller.steve@gmx.de>: Oct 10 03:55PM +0200


> It only causes duplication if you take the address and return a
> pointer. Why do that for a constant defined in a header?
 
But taking the address is very common, e.g. if the object is an array.
In fact, before I posted my first example with 'const int a = 42;' I
had observed the behavior with const char arrays. Here You see the
duplication if you put it as non-extern const into a header file:
 
$ cat foo.hh
const char s[] = "This is a string";

void bar();
$ cat x.cc
#include <iostream>

#include "foo.hh"

void bar() { std::cout << s; }
$ cat y.cc
#include <iostream>

#include "foo.hh"

int main()
{
bar();
std::cout << s;
}
$ g++ -Os -o foo x.cc y.cc
$ strings -a foo | grep This
This is a string
This is a string
 
So, I still don't see the purpose of defining const global objects as
internal linkage implicitly so you can put them into a header file.
If I'd want that I could also put a 'static' qualifier. But usually
you'd wouldn't want that anyway except for basic types and instead
define it once in one TU and declare it as external in the hear file
(if it's simple enough that initialization order doesn't matter). And
then we would have more compatability to C and less surprise for C
programmers (which I have been for a long time).
 
Steve
Paavo Helde <myfirstname@osa.pri.ee>: Oct 10 05:28PM +0300

10.10.2021 16:55 Steve Keller kirjutas:
> $ strings -a foo | grep This
> This is a string
> This is a string
 
For having only one string the duplicates need to be removed at link
time, so one needs -flto here. Also you should avoid to explicitly
define two different arrays as indeed these would need to be different
objects.
 
With the following changes I get one string only in the final executable:
 
$ cat foo.hh
const char* const s = "This is a string";
void bar();
 
$ g++ -Os -o foo x.cc y.cc -flto
 
$ strings foo | grep 'This is'
This is a string
Steve Keller <keller.steve@gmx.de>: Oct 10 08:42PM +0200

> time, so one needs -flto here. Also you should avoid to explicitly
> define two different arrays as indeed these would need to be different
> objects.
 
-flto doesn't help with the source that I have shown.
 
 
> $ g++ -Os -o foo x.cc y.cc -flto
 
> $ strings foo | grep 'This is'
> This is a string
 
Yes, but then you add a const pointer variable in each TU and an
indirection with every access to the const object (it also probably
adds a number of entries to the relocation table of the executable
binary slowing startup). And I wouldn't like the superfluous
indirection when the object is at a fixed known address. Defining
only one object of type
 
const char[]
 
with external linkage is preferable IMHO. Having read in this thread
that 'const' probably originated in C++ and the designers felt that
default external linkage was wrong in the beginning, I begin to
understand the reasoning behind the C++ const behavior. Whether I can
make myself to like it, ... I don't know.
 
Steve
Paavo Helde <myfirstname@osa.pri.ee>: Oct 10 10:44PM +0300

10.10.2021 21:42 Steve Keller kirjutas:
 
>> $ strings foo | grep 'This is'
>> This is a string
 
> Yes, but then you add a const pointer variable in each TU
 
In each TU which uses it, most probably, and even then it has good
chances to be completely optimized away.
 
And we need to put this thing into context. For example, a set of CUDA
runtime libraries is 960 MB. A pointer of 8 bytes, duplicated in 10 TU-s
which make use of it would consume 80 bytes. This is 0.000008% of CUDA
libraries. Nobody will care about such things nowadays (except a certain
one frequent poster in this group, and this is not me).
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Oct 09 07:55PM -0700

On 10/9/2021 12:29 AM, Branimir Maksimovic wrote:
 
>> https://en.wikipedia.org/wiki/Diffusion-limited_aggregation
 
>> Thanks.
> Works! thanks!
 
Perfect! All right. Cool. Thanks again. Btw, I made a new test animation
in 3d:
 
https://www.youtube.com/watch?v=2gznap7wLeQ
Bonita Montero <Bonita.Montero@gmail.com>: Oct 10 06:42AM +0200

Am 09.10.2021 um 22:13 schrieb Chris M. Thomasson:
>>   if failure or suspension of any thread cannot cause failure
>>   _or suspension of another thread_".
 
> You think lock-free is crap. ...
 
Everything lock-free except from lock-free stacks is crap.
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Oct 09 10:04PM -0700

On 10/9/2021 9:42 PM, Bonita Montero wrote:
>>>   _or suspension of another thread_".
 
>> You think lock-free is crap. ...
 
> Everything lock-free except from lock-free stacks is crap.
 
Whatever you say man! ;^o
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: