Advertisement

Linus Torvalds and his smackdown speech

Started by August 13, 2012 01:02 AM
31 comments, last by Heath 12 years, 5 months ago

Anyway, whether or not one likes what some particular person has written in some particular language, this hardly gives a leverage to judge on the language itself.


Q F Fing T. That one needs to be written on a mountaintop in 50 foot high letters of fire.

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.

A good C++ programmer should always be aware of what the equivalent C code is (or better -- what the equivalent asm code is). As you can see, the C++ code has made it extremely easy to generate a LOT of (equivalent) C code -- this is what Linus is afraid of. An inexperienced coder will default to using solutions that look fine in C++, but look crazy when actually written out manually in C. His thought is that if he forces people to type this code out manually, then they'll think twice about it (assuming you've written in C before, have you ever written anything like the above C code? I bet not, even though it's so tempting to do so from C++). He thinks that being able to easily write this code in C++, means that all his contributors will automatically default to bloated, under-thought, over-engineered solutions... and he might be right.


I'm not convinced by this argument - I'd say we should judge a language by what it looks like in that language, not what it would look like when translated into another language. Performance is dependent on factors such as the choice of algorithm, or data access, and I would argue what's most important is being able to write good fast algorithms or arrange data in a way good for performance. If the code looks more complex, it's harder to track down those issues. I'm not convinced that the code that looks simplest in C is therefore the quickest.

2) Yes, it is fair to say that typical OO doesn't fit with highest performance code. The big failing of (and also the core idea of) OO is that it's a good idea to bind together data-layouts and data-transformations together into a single entity: the class. This was fine in the 70's when it was invented, but since then, CPU performance has doubled yearly, while memory performance only goes up 10% per year. This means that in 2012, the biggest bottleneck is memory access speeds, which makes data-layouts very important when optimising code. The fact of the matter is that different transformations are better suited to different layouts, so binding every transform to a single layout is a very bad idea. You're forced into trying to find the "one true layout", which usually doesn't exist.

Because of this, you'll find that a lot of the 'rock star' engine programmers are now championing what they call DOD - data oriented design, instead of OOD - object oriented design.
[/quote]Whilst DOD may be different from strict OOD, it's not clear to me that this is an argument against OO in general, or C++. One can still think in terms of OO, just that your objects are not things like a single polygon or sprite or player, but collections of things like meshes, particle systems or groups of players. One can still take advantage of concepts like encapsulation, inheritance and polymorphism, and one can still write DOD code with C++. On the flip side, it's possible for C programmers to make the same mistake - you still have structs, and one can still make the mistake of arranging data on the level of a single object, in a manner that is poor for performance.

http://erebusrpg.sourceforge.net/ - Erebus, Open Source RPG for Windows/Linux/Android
http://conquests.sourceforge.net/ - Conquests, Open Source Civ-like Game for Windows/Linux

Advertisement

Whilst DOD may be different from strict OOD, it's not clear to me that this is an argument against OO in general, or C++. One can still think in terms of OO, just that your objects are not things like a single polygon or sprite or player, but collections of things like meshes, particle systems or groups of players. One can still take advantage of concepts like encapsulation, inheritance and polymorphism, and one can still write DOD code with C++. On the flip side, it's possible for C programmers to make the same mistake - you still have structs, and one can still make the mistake of arranging data on the level of a single object, in a manner that is poor for performance.


This is kind of begging the question. There will always be entities when viewed from the outside. The difference in DOD and OOD is that those entities don't have corresponding single objects in DOD. You have collections of pieces with corresponding entities. They are decidedly different, and if you think of DOD in OOD terms you will do a sub standard job of it; inheritance and polymorphism shouldn't really be relevant in DoD for example.
Templates and dynamic linking.
Linking between different compilers.
C++11 [font=courier new,courier,monospace]noexcept [/font]or whatever this is by standard.
http://www.stroustrup.com/bs_faq.html
"C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do it blows your whole leg off". Yes, I said something like that (in 1986 or so). What people tend to miss, is that what I said there about C++ is to a varying extent true for all powerful languages. As you protect people from simple dangers, they get themselves into new and less obvious problems. Someone who avoids the simple problems may simply be heading for a not-so-simple one. One problem with very supporting and protective environments is that the hard problems may be discovered too late or be too hard to remedy once discovered. Also, a rare problem is harder to find than a frequent one because you don't suspect it.[/quote]
It's still my language of choice.
Eat flaming death, GC mongrels!

Previously "Krohm"

I'm not convinced by this argument - I'd say we should judge a language by what it looks like in that language, not what it would look like when translated into another language. Performance is dependent on factors such as the choice of algorithm, or data access, and I would argue what's most important is being able to write good fast algorithms or arrange data in a way good for performance. If the code looks more complex, it's harder to track down those issues. I'm not convinced that the code that looks simplest in C is therefore the quickest.
Neither me or anyone else made that argument...!...?
The point of mentally translating your C++ code to C code is to be aware of the actual meaning of what you're writing. If you can't carry out this exercise, then you don't really understand C++ and are a danger to your project. In the *specific* example given, you can see that the vtable is simply a completely useless extra layer of indirection, and only serves to force an extra cache miss and a branch misprediction for no reason. In that simple example, then moving the DoStuff function pointer out of the vtable struct and into the A struct would remove these performance costs (and coincidentally make the C code look simpler), however, the typical C++ programmer would default to using the unnecessary vtable implementation simply because it's easy.
Simpler looking C code being faster isn't always the case, but this specific case demonstrates why it's an important mental exercise nonetheless.

Also the point of this straw-man example (where translating to C shows how some typical looking C++ code is actually making retarded performance-decisions) was not meant as an attack on C++, but as an explanation for why Linus might prefer his contributors to write in C over C++ -- i.e. He doesn't trust his contributors to think through their use of C++ features thoroughly. This is a project-specific management decision.

Whilst DOD may be different from strict OOD, it's not clear to me that this is an argument against OO in general, or C++. One can still think in terms of OO, just that your objects are not things like a single polygon or sprite or player, but collections of things like meshes, particle systems or groups of players. One can still take advantage of concepts like encapsulation, inheritance and polymorphism, and one can still write DOD code with C++. On the flip side, it's possible for C programmers to make the same mistake - you still have structs, and one can still make the mistake of arranging data on the level of a single object, in a manner that is poor for performance.
[/quote]No, this had nothing to do with C or C++. I see DOD being orthogonal to, and often compatible with OOD - it requires an augmentation of your OO designs, and can make use of OOP tools in it's implementations.
N.B. it's not as simple as "OO is single objects; DO is collections" - that's a common manifestation of the core ideas, but not the core ideas themselves.
There can be simpler manifestations, such as taking a typical OO class with many methods, but splitting it into two versions of the same class, each with their own subset of the original methods, and each with their own data-layout that is optimized for its set of methods.
This was more an admission that OO is based on some performance fallacies, and has to be adapted/used with careful thought if its to be used optimally in HPC.

It's still my language of choice.


I agree, C++ is my first choice also.
Advertisement
The point of mentally translating your C++ code to C code is to be aware of the actual meaning of what you're writing. If you can't carry out this exercise, then you don't really understand C++ and are a danger to your project.
This was a fairly strong statement, so I decided to test myself and take my previous example of a virtual function, and translate it over to C. I then took the C implementation and "optimized" it by folding the vtable into the object (seeing that there was only one function in the vtable, this should be a space saving), which, in theory, reduces the complexity of calling the "virtual" function.

I tested each implementation by calling the virtual function on an object of the derived type (where the compiler should be able to resolve the polymorphism at compile time) and also through a pointer to the bass class (so dynamic-dispatch must be performed).

I was very surprised by the results. All 3 performed the exactly same when calling the function on the derived type (I was kinda suprised that the C++ compiler optimised out the 'virtual' overhead in this case!), but when calling the function via the base, things got weird. The straightforward C++ version won outright. The C translation was almost the same, but the compiler didn't optimise it as well, so it was slightly slower. The optimised C++ version produced much simpler assembly as predicted, but for some reason was slower! I've yet to figure out why, but I'm pretty intrigued.

Here's my test:
http://pastebin.com/X2s5Nne6


tl;dr: I set up a C++ straw-man to show how reliance on C++'s features can be slow... but proved the opposite?blink.png
Or I just proved that optimisations aren't intuitive?huh.png
Or that I'm a bad programmer and a danger to my project? wink.png
I think you might have just proven the point we're always trying to make when we tell beginners not to be overly concerned with optimization because the compiler is almost certainly smarter. smile.png

- Jason Astle-Adams


[quote name='Hodgman' timestamp='1345010440' post='4969749']The point of mentally translating your C++ code to C code is to be aware of the actual meaning of what you're writing. If you can't carry out this exercise, then you don't really understand C++ and are a danger to your project.
This was a fairly strong statement, so I decided to test myself and take my previous example of a virtual function, and translate it over to C. I then took the C implementation and "optimized" it by folding the vtable into the object (seeing that there was only one function in the vtable, this should be a space saving), which, in theory, reduces the complexity of calling the "virtual" function.

I tested each implementation by calling the virtual function on an object of the derived type (where the compiler should be able to resolve the polymorphism at compile time) and also through a pointer to the bass class (so dynamic-dispatch must be performed).

I was very surprised by the results. All 3 performed the exactly same when calling the function on the derived type (I was kinda suprised that the C++ compiler optimised out the 'virtual' overhead in this case!), but when calling the function via the base, things got weird. The straightforward C++ version won outright. The C translation was almost the same, but the compiler didn't optimise it as well, so it was slightly slower. The optimised C++ version produced much simpler assembly as predicted, but for some reason was slower! I've yet to figure out why, but I'm pretty intrigued.

Here's my test:
http://pastebin.com/X2s5Nne6


tl;dr: I set up a C++ straw-man to show how reliance on C++'s features can be slow... but proved the opposite?blink.png
Or I just proved that optimisations aren't intuitive?huh.png
Or that I'm a bad programmer and a danger to my project? wink.png
[/quote]

Bad programmer? Not at all, you have at least found an issue and know how to look for it, and fix it hopefully, I would say that makes a decent programmer at the very least! :)

Bad would have been assuming it was the best, and having no idea how to fix it, or if it was even an issue... IMO
Initially his views on C++ were from the point of view of how people unfamiliar with C or even programming in general, would use it, rather than from the point of view of a good C programmer who can see what extra features are actually quite a blessing, e.g. destructors, templates. and actually understands how they work in terms of the code generated for them.

Then it got worse. He would rather bend over backwards trying to code up in C the equivalent of anything that is part of C++ but not C.
I would call it a phobia or an obsession, but it's worse than that, it's actually more like a religeous belief. With his massive ego he would never admit that he was wrong. They don't call him arrogant for nothing.

Lately his critical reasoning skills add up to no more than swearing, insulting, berating anyone and everyone, and declaring his own opinion to be gospel, in complete disregard to any and all evidence to the contrary.
These days everything I read suggests that he belongs in a psychiatric institution.
"In order to understand recursion, you must first understand recursion."
My website dedicated to sorting algorithms

This topic is closed to new replies.

Advertisement