- Available C++ Libraries FAQ - 1 Update
- Why should a "c" programmer learn c++ ? (V2) - 5 Updates
- max without ifs - 16 Updates
- Cause error if integral parameter too large - 1 Update
- Are there any asm-instructions to support OOP - 1 Update
- Porting C++ code to C - 1 Update
Nikki Locke <nikki@trumphurst.com>: Sep 14 10:23PM Available C++ Libraries FAQ URL: http://www.trumphurst.com/cpplibs/ This is a searchable list of libraries and utilities (both free and commercial) available to C++ programmers. If you know of a library which is not in the list, why not fill in the form at http://www.trumphurst.com/cpplibs/cppsub.php Maintainer: Nikki Locke - if you wish to contact me, please use the form on the website. |
olcott <NoOne@NoWhere.com>: Sep 14 09:55AM -0500 On 9/14/2020 2:58 AM, Christian Hanné wrote: > If someone new to C would learn C++ I'd recommend Visual C++ > becuase it's a more visual language. It's rather like Logo. Not not at all not in the least. It is a rats nest of complexity. -- Copyright 2020 Pete Olcott |
David Brown <david.brown@hesbynett.no>: Sep 14 05:01PM +0200 On 14/09/2020 16:55, olcott wrote: >> If someone new to C would learn C++ I'd recommend Visual C++ >> becuase it's a more visual language. It's rather like Logo. > Not not at all not in the least. It is a rats nest of complexity. The poster was surely joking! |
Real Troll <real.troll@trolls.com>: Sep 14 05:10AM -1000 On 14/09/2020 14:17, Richard Harnden wrote: > An IBM man-year .. 730 guys trying to get it done by lunch. So it was all about too many cooks !!!! Did they spoil the broth? |
olcott <NoOne@NoWhere.com>: Sep 14 10:15AM -0500 On 9/10/2020 7:08 AM, David Brown wrote: > (At least, that is my understanding - IANAL.) > So the real question is, why bother putting a copyright message on the > post when it is already covered automatically? Because unlike most of the posts on Usenet I need to distinguish that my posts related to the Halting Problem, Russell's Paradox, Gödel's 1931 Incompleteness Theorem and the Tarski Undefinability Theorem are mostly brand new ideas originated by myself and not merely a rehash of what others have said. Although it is technically correct that a copyright arises whenever an idea is put in fixed form most of the ideas presented on USENET are mostly rehashes of the ideas of others. Because of this most people would not generally carefully apply copyright law to USENET posts and might consider some of my brand new ideas simply as rehashes of existing ideas. Here is the fundamental flaw in Gödel's 1931 Incompleteness Theorem: A theory T is incomplete if and only if there is some sentence φ such that (T ⊬ φ) and (T ⊬ ¬φ). The definition of incompleteness decides that every formal system that cannot prove or refute self-contradictory sentences is incomplete entirely on the basis that the formal system cannot prove or refute self-contradictory sentences. -- Copyright 2020 Pete Olcott |
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Sep 14 01:20PM -0700 On 9/14/2020 3:55 AM, Real Troll wrote: > than billion lines of code to be written or re-written using c# so it > takes time!!. Microsoft can't hire all the C# programmers to speed up > the process. I want to see the Kernel written in C#. That would be a trip. Fwiw, here is the full source code to the WinNT 4 kernel: https://github.com/ZoloZiak/WinNT4 Not sure if garbage collection is a "good idea" here. |
James Kuyper <jameskuyper@alumni.caltech.edu>: Sep 14 09:58AM -0400 On 9/14/20 8:42 AM, Öö Tiib wrote: > } > It has no undefined behaviours I hope and where it does compile there > it seems to work. Demo: "undefined behavior" is defined by the C standard as behavior not defined by the C standard, even if a particular implementation provides it's own definition for the behavior. Your code uses the identifier __builtin_ssub_overflow, which is not defined by the C standard, and is reserved by that standard for all uses. Declaring or defining that identifier yourself would render the behavior of your program undefined. Using it when it has been declared or defined by the implementation (which is presumably the case on your system) has behavior that depends entirely upon how the implementation defined __builtin_ssub_overflow(). It could be a syntax error, a constraint violation, or have undefined behavior - or it might do precisely what you expect it to do. Using that identifier in this manner when neither your own code nor the implementation has provided a declaration or definition for it would be a constraint violation: at least one diagnostic is mandatory, and producing an executable program is optional. Should an implementation choose to generate an executable program, and if you should choose to execute it, the behavior is undefined. |
Ben Bacarisse <ben.usenet@bsb.me.uk>: Sep 14 03:05PM +0100 > I wanted somehow at weekend to find maximum of two int32_t-s without > branches (like ifs or ? operators) in C++. You are trying to beat the compiler. Both std::max and the simple code using ?: are optimised by gcc to minimal branch-free code. You function comes out more than twice as long. > } > It has no undefined behaviours I hope and where it does compile there > it seems to work. You have implementation-defined behaviour, though, in the signed shift when d is negative. And you are assuming that int32_t matches int. > <http://coliru.stacked-crooked.com/a/19eca82b689292e5> > However with raw C++ I am in trouble. Does anyone have some idea > how to do the trick in raw C++? I presume "raw" means no std::max? -- Ben. |
David Brown <david.brown@hesbynett.no>: Sep 14 04:16PM +0200 On 14/09/2020 14:42, Öö Tiib wrote: > <http://coliru.stacked-crooked.com/a/19eca82b689292e5> > However with raw C++ I am in trouble. Does anyone have some idea > how to do the trick in raw C++? How about: int32_t mad_max2(int32_t a, int32_t b) { return a > b : a ? b; } Write the source clearly, and let the /compiler/ generate the appropriate object code. It is likely to do a better job than you in most cases. To start with, why do you think avoiding branches is useful? /Sometimes/ it is - but depending on the target processor, the predictability of the branch, and the surrounding code, branches can sometimes be handled in the cpu's decoder units before they even make it to the execution units. That's zero cost. Let the compiler put in a branch if that's what suits with the rest of the instructions in the code. The typical code for mad_max2 for generic x86_64 cpus is: mad_max2(int, int): cmp edi, esi mov eax, esi cmovge eax, edi ret No branches. But since a function like this is likely to be inlined, the details in practice will depend on the surrounding code. And don't bother with x86 intrinsics. If you know more about the target processor, and know what instruction sets it supports, then tell the compiler about them with "-march" flags. Then it will generate pmaxsd instructions or whatever suits best. |
David Brown <david.brown@hesbynett.no>: Sep 14 04:21PM +0200 On 14/09/2020 14:53, Bonita Montero wrote: > int32_t mask = a < b ? -1 : 0; > return a & ~mask | b & mask; > } That is a little less bad than the OP's suggestion, as it is reasonably comprehensible. But it is still a dog's breakfast. It's twenty years or more since it has made any sense to write this sort of gibberish in anything but the most specialised of circumstances. |
"Öö Tiib" <ootiib@hot.ee>: Sep 14 08:12AM -0700 On Monday, 14 September 2020 17:05:50 UTC+3, Ben Bacarisse wrote: > > it seems to work. > You have implementation-defined behaviour, though, in the signed shift > when d is negative. And you are assuming that int32_t matches int. That implementation-defined is flaw that I asked ideas of how to get rid of. If that assumption does not hold then the code is ill-formed so I did not bother to add additional static_asserts doing same into example that is not what I wanted to achieve anyway. > > However with raw C++ I am in trouble. Does anyone have some idea > > how to do the trick in raw C++? > I presume "raw" means no std::max? Yes, since it is unknown if that std::max uses branches or does not. Actually same is unknown about __builtin_ssub_overflow but gcc docs say they try their best. |
Tim Rentsch <tr.17687@z991.linuxsc.com>: Sep 14 08:26AM -0700 > <http://coliru.stacked-crooked.com/a/19eca82b689292e5> > However with raw C++ I am in trouble. Does anyone have some idea > how to do the trick in raw C++? Neither for() nor if() nor switch() now while() nor ?: is needed for Turing completeness: static int give_a( int a, int b ){ return a; } static int give_b( int a, int b ){ return b; } int no_control_max( int a, int b ){ int (*choose[2])( int, int ) = { give_a, give_b }; return choose[ b > a ]( a, b ); } Compiles cleanly as both C{90,99,11} and C++{98,03,11,14,17}. |
scott@slp53.sl.home (Scott Lurndal): Sep 14 03:35PM >comprehensible. But it is still a dog's breakfast. >It's twenty years or more since it has made any sense to write this sort >of gibberish in anything but the most specialised of circumstances. Given the intel/amd 'CMOVxx' instruction and the ARM "CSET" instruction, the compilers will generate the most optimal branchless code for a max check even without optimization. |
"Öö Tiib" <ootiib@hot.ee>: Sep 14 08:46AM -0700 On Monday, 14 September 2020 17:17:08 UTC+3, David Brown wrote: > int32_t mad_max2(int32_t a, int32_t b) { > return a > b : a ? b; > } Thanks, that is same what std::max compiles to. Unfortunately there is branch on RISC-V (for example) while my convoluted gibberish did not have branch. > mov eax, esi > cmovge eax, edi > ret I know, but when the target isn't x86_x64 there can be branches. > processor, and know what instruction sets it supports, then tell the > compiler about them with "-march" flags. Then it will generate pmaxsd > instructions or whatever suits best. That was my hope to get rid of whatever (not exactly x86 but gcc) specific. |
Bonita Montero <Bonita.Montero@gmail.com>: Sep 14 05:49PM +0200 >> } > That is a little less bad than the OP's suggestion, as it is reasonably > comprehensible. But it is still a dog's breakfast. It works if the compiler supports this trick. But support for this is very common. |
"Öö Tiib" <ootiib@hot.ee>: Sep 14 10:01AM -0700 On Monday, 14 September 2020 18:49:29 UTC+3, Bonita Montero wrote: > > comprehensible. But it is still a dog's breakfast. > It works if the compiler supports this trick. > But support for this is very common. Yes it works where it works, thanks. David is also correct that what std::max does (a > b ? a : b) is also often without branches on such platforms. |
Bonita Montero <Bonita.Montero@gmail.com>: Sep 14 07:08PM +0200 > Yes it works where it works, thanks. David is also correct that what > std::max does (a > b ? a : b) is also often without branches on > such platforms. std::max normally maps to "a > b ? a : b" and and this results usually in a branch where a predicated move isn't possible. The trick I've shown is common with most compilers and today's compilers detect what's going on there and further replace it with a conditional move. So you have both: a conditional move on platforms that support it and a non-branched version on platforms that usually would use a branch. And I think the SSE-code would be rather slow as you would have to store the GPR-register into memory and then from memory to the SSE-register and then the way back. |
David Brown <david.brown@hesbynett.no>: Sep 14 08:19PM +0200 On 14/09/2020 17:49, Bonita Montero wrote: >> comprehensible. But it is still a dog's breakfast. > It works if the compiler supports this trick. > But support for this is very common. I can't imagine a compiler that would recognize the pattern you've given here and generate decent code, but would fail to give at least as good results for the simple, clean, obvious "max" expression. Code like you've given here should be rejected by any code review if it is not accompanied with detailed test results showing exactly why the "max" function is performance critical, and demonstrating that this source code gives significant measurably better results than the simple version. Code like the OP's, however, should be rejected outright - with a suggestion that the programmer re-think his or her priorities in writing code. |
Bonita Montero <Bonita.Montero@gmail.com>: Sep 14 08:22PM +0200 > I can't imagine a compiler that would recognize the pattern you've given > here and generate decent code, but would fail to give at least as good > results for the simple, clean, obvious "max" expression. Usually it results in "cmp regA, regB; sbb regC, regC" if the compiler doesn't detect the data-flow and further replaces it with a CMOV if possible. I used this pattern a long time ago and it was supported by MSVC and gcc. > "max" function is performance critical, and demonstrating that this > source code gives significant measurably better results than the simple > version. Idiocracy ... |
David Brown <david.brown@hesbynett.no>: Sep 14 08:25PM +0200 On 14/09/2020 17:46, Öö Tiib wrote: > Thanks, that is same what std::max compiles to. Unfortunately there > is branch on RISC-V (for example) while my convoluted gibberish did > not have branch. Have you done comprehensive tests showing that your function here is performance critical to the code, that your gibberish is actually faster than simple branched code, and that this applies even when used in /real/ code where the simple version can be used for further optimisation, unlike your gibberish? I strongly suspect not. >> cmovge eax, edi >> ret > I know, but when the target isn't x86_x64 there can be branches. So what? On many targets, branches are cheap. On those that are not, the compiler will avoid branches. And if the target port is relatively young on gcc (like RISC-V) and not well optimised as yet, then messing around with this stuff is just bikeshedding. |
"Öö Tiib" <ootiib@hot.ee>: Sep 14 11:52AM -0700 On Monday, 14 September 2020 21:25:28 UTC+3, David Brown wrote: > than simple branched code, and that this applies even when used in > /real/ code where the simple version can be used for further > optimisation, unlike your gibberish? I strongly suspect not. If you think that I somehow considered it as good and useful example of programming then it is incorrect. Possibly it is miscommunication of mine that you have such impression. I only wanted to demonstrate that the weird code gives correct answers and has no branches on platforms with overflow flag. > the compiler will avoid branches. And if the target port is relatively > young on gcc (like RISC-V) and not well optimised as yet, then messing > around with this stuff is just bikeshedding. I know. I did try to mention that I did it at weekend. And shared without desire to spoil anyone's mood, sorry. ;) |
David Brown <david.brown@hesbynett.no>: Sep 14 09:39PM +0200 On 14/09/2020 20:52, Öö Tiib wrote: > mine that you have such impression. I only wanted to demonstrate that > the weird code gives correct answers and has no branches on platforms > with overflow flag. Ah, okay. That makes more sense. My apologies if I misunderstood your intentions. I have many times seen people write "smart-arse" code, thinking it was a good idea, when almost invariably it is not. Having had to deal with such code on occasion, I react strongly against it when I see it. I must admit I thought it was odd to see it coming from you! >> around with this stuff is just bikeshedding. > I know. I did try to mention that I did it at weekend. And shared > without desire to spoil anyone's mood, sorry. ;) Fair enough. One thing that might come out of this would be how gcc handles the simple max code in gcc for RISC-V. If the code is not optimal (I don't know the RISC-V well enough to tell) and there is a better branchless pattern, then it could be worth filing it as a missed optimisation bug in gcc. It's always useful for them to get common patterns into the peephole optimiser for each target. |
Udo Steinbach <trashcan@udoline.de>: Sep 14 05:45PM +0200 void func(std::uint64_t); // not implemented void func(std::uint32_t); calls with other types are ambiguous, compile error. or add an indirection. void funcImpl(std::uint32_t); template<typename T> inline void func(T Value) { static_assert(CheckTheType); assert(CheckTheValue); funcImpl(Value); } or make it nonconvertible struct MyValue { uint32_t V; } void func(uint64_t); void func(MyValue); func(MyValue{12344}); But my favorite is: Don't try to solve social problems with tech. Document it, users have to read and follow. -- Fahrradverkehr in Deutschland: http://radwege.udoline.de/ GPG: A245 F153 0636 6E34 E2F3 E1EB 817A B14D 3E7E 482E |
scott@slp53.sl.home (Scott Lurndal): Sep 14 03:31PM >CPUs like consecutive memory accesses and dislike memory accesses that >jump in large steps, or randomly. How OOP has been implemented inevitably >leads to the latter, which is bad for performance. Where did you get the idea that CPUs like consecutive memory accesses? Modern cache subsystems and store buffers accomodate non-consecutive memory accesses rather well (with 90%+ hit rates for most applications). >program execution is going to go. If they don't see it, or if they >"guess" it wrong, it causes a performance penalty. Virtual functions >largely work against this, causing even more performance hits. Again, modern processors handle this rather well using techniques such as branch target buffers and return stack caches. >OOP implementations oftentimes hinder compiler optimizations, eg. when it >comes to autovectorization. It's relatively easy to show practical >examples of this. Please do. Also note the relatively small number of code sequences that are actually amenable to autovectorization. |
Leo <usenet@gkbrk.com>: Sep 14 06:11PM +0300 On 8/17/20 2:51 PM, Frederick Gotham wrote: > I hear that "glib" is the best library for C that gives the functionality of the C++ standard library and also Boost. > Looking through the 'glib' reference manual here though, I don't see anything similar to "std::next_permutation". > Is glib the best thing to use for porting C++11 code to C if you're looking for functionality similar to <algorithm> <numeric> <functional>? For a microcontroller, you will probably be served better by using a smaller library and compiling with -Os and -flto to clean up all the unused stuff. |
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:
Post a Comment