News for hackers. Stuff that matters.
Re:C and C++ Prioritize Performance over Correctness by Filligree on Friday August 18, 2023 @01:27PM (#37179075)
Maybe the idea hadn't been invented back then, but it seems obvious to me that the correct response is an iterator protocol. Or at least a hardcoded for-in syntax.
Re:C and C++ Prioritize Performance over Correctness by dahfizz on Friday August 18, 2023 @01:33PM (#37179173)
Care to explain? An iterator is a nice high level concept, but the CPU still has to do the &in + i + offset arithmetic. I don't see how replacing `i` with syntactic sugar changes the need to check for overflow.
Re:C and C++ Prioritize Performance over Correctness by nostrademons on Friday August 18, 2023 @01:48PM (#37179436)
I think the point the GP is making is that with an iterator protocol, the iterator implementation itself is free to make a different choice on implementation strategies, based on the shape of the data and the hardware available, and this is transparent to client code. So for example, a container containing only primitive ints or floats on a machine with a NVidia Hopper GPU might choose to allocate arrays as a multiple of 64, and then iterate by groups of 64, taking advantage of the full warp without needing any overflow checks. Obviously a linked list or an array of strings couldn't do this, but then, they wouldn't want to, and hiding the loop behind an iterator lets the container choose the appropriate loop structure for the format and hardware.

I've heard criticisms of C and C++ that they are simultaneously too high-level and too low-level. Too high-level in that the execution model doesn't actually match the sort of massively parallel numeric computations that modern hardware gives, and too low-level that the source code input into the compiler doesn't give enough information about the real structure of the program to make decisions that really matter, like algorithm choice.

It's interesting that the most compute-intensive machine learning models are actually implemented in Python, which doesn't even pretend to be low-level. The reason is because the actual computation is done in GPU/TPU-specific assembly, so Python just holds the high-level intent of the model and the optimization occurs on the primitives that the processor actually uses.

Re:C and C++ Prioritize Performance over Correctness by dahfizz on Friday August 18, 2023 @02:28PM (#37180020)
> the iterator implementation itself is free to make a different choice on implementation strategies

That's just UB with more steps. What will the spec say? "Behavior of integer overflow is undefined. Unless the overflow happens within an iterated for loop, in which case the behavior is undefined and the iterator can do whatever it wants".

> I've heard criticisms of C and C++ that they are simultaneously too high-level and too low-level.

I've heard this as well, and I think there is some truth to it, but C is the least-bad offender relative to any other language.

C maps extremely well to assembly. The fact that assembly no longer perfectly captures the implementation of the CPU has nothing to do with C. Every other general purpose[1] language has to target the same abstraction that C does.

Given that reality, C in fact maps better to the hardware than any other language. Because it is faster than any other language. Any higher level language that gives the compiler more information about algorithm choice is slower than C is. That's the bottom line.

[1] This is ignoring proprietary, hardware specific tools like CUDA. That's clearly in a different category when discussing programming languages, IMO.

Re:C and C++ Prioritize Performance over Correctness by nostrademons on Friday August 18, 2023 @04:21PM (#37181559)
The reasoning behind the decision to make integer overflow UB changes. As the thread starter mentioned, that reasoning was loops, so you don't need an overflow counter for everyday loops. Take loops out of the equation, and take certain high-performance integer computations where arguably you should have a dedicated FixedInt type, and the logical spec behavior might be silent promotion to BigInt (like JS, Python 3, Lisp, Scheme, Haskell) or a panic (like in Rust).

> [1] This is ignoring proprietary, hardware specific tools like CUDA. That's clearly in a different category when discussing programming languages, IMO.

Arguably they should be part of the conversation. One main reason for the recent ascendancy of NVidia over Intel is that they're basically unwrapping all the layers of microcode translation that Intel uses to make a modern superscalar processor act like an 8086, and saying "Here, we're going to devote that silicon to giving you more compute cores, you figure out how to use them effectively."

Re:C and C++ Prioritize Performance over Correctness by PaulDavisThe1st on Friday August 18, 2023 @02:05PM (#37179690)
"It's interesting that a lot of performance-critical code tends to be written in C++, which sometimes pretends not to be that low level. The reason is because the actual performance critical code is really running CPU-specific assembly, so C++ just holds the high level intent of the model and the optimization happens on the primitives that the processor actually uses."
Re:C and C++ Prioritize Performance over Correctness by commonlisp94 on Friday August 18, 2023 @05:12PM (#37182173)
> implemented in Python,

A program which constructs an AST out of python classes and spits out GPU code is a compiler. The python is never executed.

Trivially, compilers can generate code faster than their hose language, but that doesn't make the host language fast. The compiler would be even faster if it were written in C++.

Re:C and C++ Prioritize Performance over Correctness by nostrademons on Friday August 18, 2023 @11:01PM (#37185051)
That's sort of the point. If you want to make programs really fast and really expressive, your target language ought to be as close to the hardware as possible, and your source language ought to be as expressive as possible, and then you just write a compiler to translate between them.
Re:C and C++ Prioritize Performance over Correctness by alexvitkov on Friday August 18, 2023 @01:45PM (#37179379)
Adding an iterator in C++ means adding at least 2 more objects, multiple function calls, operator overload, templates, the whole package.

You don't trust your compiler to optimize the sane trivial C case, but you trust it to optimize all that garbage away?

Re:C and C++ Prioritize Performance over Correctness by RicardoLuis0 on Friday August 18, 2023 @03:06PM (#37180557)
if your data's sequential, creating an iterator in C++ is as simple as returning a begin and end pointer, and will be optimized away by any level other than O0

https://godbolt.org/z/WEjzEr5j4

Re:C and C++ Prioritize Performance over Correctness by josefx on Friday August 18, 2023 @03:30PM (#37180887)
But iterating over pointers is once again optimized with lots of undefined behavior at the corners. So you are replacing one source of undefined behavior with another.
Re:C and C++ Prioritize Performance over Correctness by yazaddaruvala on Friday August 18, 2023 @04:10PM (#37181435)
Pointer arithmetic optimization based on undefined behavior is a problem regardless.

Life is always better after minimizing the total number of types of undefined behavior.

Re:C and C++ Prioritize Performance over Correctness by AYoung010 on Friday August 18, 2023 @04:14PM (#37181479)
Replacing undefined behavior at the program-level with undefined behavior written and tested as part of the standard library, usually vendored and distributed in concert with the compiler, seems like an obvious net-positive to me.
Re:C and C++ Prioritize Performance over Correctness by commonlisp94 on Friday August 18, 2023 @05:09PM (#37182138)
> with lots of undefined behavior at the corners.

What behavior is undefined in incrementing a pointer between a begin and end range?

Re:C and C++ Prioritize Performance over Correctness by josefx on Friday August 18, 2023 @06:05PM (#37182768)
Of course a basic iteration between begin()/end() will never contain out of range elements, but neither will valid increment between two integers. No need for iterators in that case either.

Say I want to do something fancy, like getting element number 11 from an array.

With an integer index I can pass 11, with random access iterators I can use begin() + 11.

Now my array only has five elements. So I check.

11 < 5? Comparison valid, successfully avoided a crash.

begin() + 11 < end() ? How where the rules for pointer comparison again, something about within an allocation and one past the end?

Re:C and C++ Prioritize Performance over Correctness by commonlisp94 on Friday August 18, 2023 @07:28PM (#37183506)
> something about within an allocation and one past the end?

Yeah, I forgot about that. So I agree there is some subtly which is likely to catch beginners.

Your example could safely be:

   if (std::distance(begin, end) > 5) 
Another approach I would recommend is to write a `guarded_advance` which takes an integer and the end pointer.

Also note that the situation you are describing is still a little unusual because the baseline assumption is it takes linear time to advance an iterator by more than 1 increment.

> but neither will valid increment between two integers. No need for iterators in that case either.

The purpose of an iterator is to abstract data structure access. The coordinate inside a complex data structure may not be representable by an integer.

Re:C and C++ Prioritize Performance over Correctness by commonlisp94 on Friday August 18, 2023 @05:08PM (#37182128)
A pointer is a valid C++ iterator.

> but you trust it to optimize all that garbage away?

Yep, if you learn about compilers you learn what kind of optimizations are easy and hard for them to make. The kind that just flattens a few levels of nested definitions are easier.

Re:C and C++ Prioritize Performance over Correctness by kimixa on Friday August 18, 2023 @02:03PM (#37179669)
If you don't initialize the initial iterator state, or compare with something that isn't a valid iterator of the same container, you kinda end up with the same issues.

The complaint here is that the warnings/errors for the integer case don't seem to be on by default. With the warnings command line flags enabled, this case is easily detected by the compiler, same as if it was some iterator object.