Experiment: C++ port of ottd

Forum for technical discussions regarding development. If you have a general suggestion, problem or comment, please use one of the other forums.

Moderator: OpenTTD Developers

Post Reply
KUDr
OpenTTD Developer
OpenTTD Developer
Posts: 219
Joined: 11 Jan 2006 21:36
Location: Czech Republic

Experiment: C++ port of ottd

Post by KUDr »

I just wanted to try it.
It took me 3 days to compile it as C++ (+ 3 days more to eliminate throwing of new asserts I added).
Then some improvements (new classes for direction, track, trackdir, and so on.)
Then new tile indexing scheme + some other experiments.
PBS works much better now (no random crashes, can reverse always).
Was it bad idea?

Then I was asked to share it.



So here it is (thanks to boekabart):
Attachments
KUDr_cppPatch_3933_diff.rar
works with MSVC2k3 only
DIFF is against 3393
there is openttd.sln, .vcproj that are modified to compile .c as C++
(119.49 KiB) Downloaded 166 times
DaleStan
TTDPatch Developer
TTDPatch Developer
Posts: 10285
Joined: 18 Feb 2004 03:06
Contact:

Post by DaleStan »

Three questions:
1) How does the memory usage compare?
2) How does the CPU usage compare?
3) How does the readability compare?
To get a good answer, ask a Smart Question. Similarly, if you want a bug fixed, write a Useful Bug Report. No TTDPatch crashlog? Then follow directions.
Projects: NFORenum (download) | PlaneSet (Website) | grfcodec (download) | grfdebug.log parser
KUDr
OpenTTD Developer
OpenTTD Developer
Posts: 219
Joined: 11 Jan 2006 21:36
Location: Czech Republic

Post by KUDr »

DaleStan:

1) How does the memory usage compare?
- no difference by language change

2) How does the CPU usage compare?
- in Release: the same
- in Debug: ca +50% - new inline functions (methods + operators) that are not inline in Debug builds

3) How does the readability compare?
- well, the readability could improve by the time. But it has nothing to do with C++. Only the new code, if it is well designed can give you better readability, lower maintenance costs and so on.

The biggest benefit I see in C++ is that compiler doesn't allow you to do typical mistakes like using trackdir instead of track without calling some conversion method. In C it is bit harder to see such problems. And there were many of them.
Sacro
Tycoon
Tycoon
Posts: 1145
Joined: 18 Jun 2005 21:08
Location: Here
Contact:

Post by Sacro »

Slight problem, PBS is no longer in the trunk so your patch needs updating.

I'm sit digging at your patch at the moment, trying to extract just the PBS fixes, I don't suppose you are able to help me with this task are you?
We Am De Best

Host of ThroughTheTube site
KUDr
OpenTTD Developer
OpenTTD Developer
Posts: 219
Joined: 11 Jan 2006 21:36
Location: Czech Republic

Post by KUDr »

Sacro:

No, this patch doesn't need update. As you can see from the subject, this is experiment.

I wanted to try and compare C++ vs. C. Not to fix PBS. I am very satisfied with the result as it can help break the myth about "slow C++ vs. fast C". There is only bit different syntax for the same things and much more strict type checks. It was obvious that changing source language can't change the execution speed.

But the PBS related code was the most problematic part for the compiler to deal with. I needed to do many changes in the PBS code to suppress errors and later also asserts (i.e. lookup behind table overruns) so please test it as it is first. And then decide if you want to isolate PBS from it. It can be the same scrap. Don't belive me, just try it.
User avatar
LordOfThePigs
Route Supervisor
Route Supervisor
Posts: 435
Joined: 01 Jul 2004 10:28
Location: Jura/Switzerland

Post by LordOfThePigs »

Hmm...

Heh, it's going to be quite tough to rewrite the whole code to use a purely OO aproach.
Session Start: Wed Jan 11 22:12:48 2006
Session Ident: #openttd
[22:25:36] <Tron> so...
[22:25:47] <Tron> ottd consists of 119 object files
[22:26:25] <Tron> these have 1366 inter-object-dependencies (object file A uses a variable/calls a function in object file B)
[22:26:43] <Tron> 108 of these object files form a strongly connected component
The slow C++ vs fast C as you say is valid only if you use a purely OO approach. Inheritance does bring quite and overhead. Replacing a few structures by classes and the syntactical changes won't make any difference, the compiler output is probably going to be the same anyway...
Sometimes I'm told "Brilliant"...
Sometimes I'm told "Charming"...
And Often I'm told "Shut Up"!
boekabart
Transport Coordinator
Transport Coordinator
Posts: 333
Joined: 25 Aug 2005 09:44
Location: Eindhoven, Netherlands

Post by boekabart »

Being a CPP programmer professionally, my first instinct when I starte programming in OpenTTd was also 'why not C++'. But, now that I'm used to it, the only thing that I think really misses in C that OpenTTd can benefit from, is the strong types checking.
Therefore I think it's a really good experiment that was done (if it's done been accurately, of course), so I think it would definately be a good idea if everyone who wrote a specific part would take a look at when KUDr had to do to make it compile as C++. Lot of changes will be trivial, but as he says himself, there were lots of apparently real type errors. I think the original coders (or people who know and understand the code really well) should take a look at those.
(And I mean not just HackyKid (PBS) :lol: )
User avatar
bobingabout
Tycoon
Tycoon
Posts: 1850
Joined: 21 May 2005 15:10
Location: Hull, England

Post by bobingabout »

i think what sacro meant is that you fixed PBS, but nobody else has yet, he wants to use your code to help him fix the current PBS, which is kinda difficult since PBS has been removed from the SVN for the up-comming stable release.
JPG SUX!!! USE PNG!!!
There are times when JPG is useful, TTD screenshots is not one of them. Please use PNG instead.

[/url]
Tron
OpenTTD Developer
OpenTTD Developer
Posts: 57
Joined: 13 Dec 2004 23:15

Post by Tron »

KUDr wrote:I am very satisfied with the result as it can help break the myth about "slow C++ vs. fast C".
Welcome in the 21st century, you're ten years or so late.
Tron
OpenTTD Developer
OpenTTD Developer
Posts: 57
Joined: 13 Dec 2004 23:15

Post by Tron »

LordOfThePigs wrote:Hmm...

Heh, it's going to be quite tough to rewrite the whole code to use a purely OO aproach.
Session Start: Wed Jan 11 22:12:48 2006
Session Ident: #openttd
[22:25:36] <Tron> so...
[22:25:47] <Tron> ottd consists of 119 object files
[22:26:25] <Tron> these have 1366 inter-object-dependencies (object file A uses a variable/calls a function in object file B)
[22:26:43] <Tron> 108 of these object files form a strongly connected component
Object files have nothing per se to do with object oriented programming.
The slow C++ vs fast C as you say is valid only if you use a purely OO approach.
There is no such thing as "pure object orientation". The paradigm of object orientation alone isn't enough to form a programming language.
Inheritance does bring quite and overhead.
bulls***.
User avatar
LordOfThePigs
Route Supervisor
Route Supervisor
Posts: 435
Joined: 01 Jul 2004 10:28
Location: Jura/Switzerland

Post by LordOfThePigs »

Tron wrote: Object files have nothing per se to do with object oriented programming.
Well, not really, the point was that even if you have tried to keep the things logically in separated files, you still ended up with basically the whole code forming a strongly connected component. From there, I wish good luck to whoever tries unspagethising the code in order to form meaninful classes and object relations...
Tron wrote: There is no such thing as "pure object orientation". The paradigm of object orientation alone isn't enough to form a programming language.
That might have been a poor choice of words. I meant that you reduce the use of global functions to the strict minimum and encapsulate whatever functions are still global as static functions in the correct class.
Tron wrote:
Inheritance does bring quite and overhead.
s***.
Ok, I'll have to admit that I'm not an expert here, but doesn't every object keep a function table, and each level of inheritance encapsulates the super-class object (including the function table). Doesn't that bring memory overhead?
Sometimes I'm told "Brilliant"...
Sometimes I'm told "Charming"...
And Often I'm told "Shut Up"!
KUDr
OpenTTD Developer
OpenTTD Developer
Posts: 219
Joined: 11 Jan 2006 21:36
Location: Czech Republic

Post by KUDr »

Tron:

thanx. What I see here is total ignorance of some "programers" that think that using C++ means slower because of language. No. This is because of more abstract design of usual OO code and programers that don't care about implementation of the classes/methods they use. It is lack of knowledge that can lead to the ineffective code, not the language itself.
But what the language can bring you is better isolation of modules. One example:
If you want to change tile indexing scheme in the current ottd, or add assert(tile < MapSize()) into tile indexing, you must first of all replace all "m[tile].m3" references by something like "GetTileByIdx(tile)->m3", then you have it isolated and you can play with asserts or tile indexing. In C++ you can do such changes in more clear way.

On the oposite way C gives you much more freedom. You don't need to care about types of variables, arguments and so on. You can use Trakdir instead of Track, if you want (and if you know what are you doing). The only problem is that nobody is perfect and everybody does mistakes. And C compiler doesn't warn you about this kind of mistake.

This is why I prefer to use C++ compiler.
User avatar
Korenn
Tycoon
Tycoon
Posts: 1735
Joined: 26 Mar 2004 01:27
Location: Netherlands
Contact:

Post by Korenn »

most of the inheritance and other object functionality only exists pre-compile time. So that will not change performance.
Tron
OpenTTD Developer
OpenTTD Developer
Posts: 57
Joined: 13 Dec 2004 23:15

Post by Tron »

LordOfThePigs wrote: Ok, I'll have to admit that I'm not an expert here, but doesn't every object keep a function table, and each level of inheritance encapsulates the super-class object (including the function table). Doesn't that bring memory overhead?
Short answer: No (you're confusing inheritence, aggregation, polymorphism and probably some more)
Long answer will follow tonight, when i have more time.

KUDr: Don't tell me, I know what a hammer and a skrewdriver are for. I also know you can use a skrewdriver as a hammer if you don't have the latter at hand.
CobraA1
Route Supervisor
Route Supervisor
Posts: 480
Joined: 07 Nov 2003 17:52
Location: USA

Post by CobraA1 »

IMHO, switching to C++ would be great. OOP allows for easier creation of data structures and algorithms that use those data structures. I'd rewrite my queue code in OOP in a heartbeat.

AND I'd have a larger incentive to implement more complex stuff such as custom airports, beause it would be much easier to implement (I'd still need to figure out the map, sprite, and UI stuff, though :( ).
Heh, it's going to be quite tough to rewrite the whole code to use a purely OO aproach.
No need to, actually. All the existing stuff can still use the older approach if you wish. C++ would merely be allowing future patches to use OOP. IMHO, not having OOP was a severe limiting factor for creating proper data structures for my queueing code.
Ok, I'll have to admit that I'm not an expert here, but doesn't every object keep a function table, and each level of inheritance encapsulates the super-class object (including the function table). Doesn't that bring memory overhead?
Yes and no. Today's modern compilers are intelligent enough to optimize away unneccessary overhead and inline stuff when possible, and honestly I've never heard of a program being too slow due to this overhead. IMHO, the fear is unfounded.

And, as Tron indicated, you're confusing some stuff.

Also, OOP is not required for C++. If you really need to do some things tlhe old way, you can do so. Lest you forget, C++ is an extention of C - anything you can do in C, you can still do in C++.
"If a man does not keep pace with his companions, perhaps it is because he hears a different drummer. Let him step to the music he hears, however measured or far away" --Henry David Thoreau
DaleStan
TTDPatch Developer
TTDPatch Developer
Posts: 10285
Joined: 18 Feb 2004 03:06
Contact:

Post by DaleStan »

I'll try to make a concise summary here, but your best bet is probably to visit the comp.lang.c++ FAQ, and read sections 19..24.
LordOfThePigs wrote:Ok, I'll have to admit that I'm not an expert here, but doesn't every object keep a function table.
Only for virtual functions, and even at that, vtables are static; they are per-class. Objects only contain vtable-pointers.
Each class that contains vfunctions maintains a vtable for its objects to call through, and each object of those types points to the appropriate vtable.
If foo is a virtual, then "obj.foo();" expands to something like "obj._vtableptr[_foo]();", where _foo is the offset in the vtable of the pointer to foo -- a compile-time constant.

Compared to direct, non-virtual call, function-call-through-vtable typically adds two extra loads (mov reg, [ptr]) before the call.

Constructors (including the copy constructor), the assignment operator, and the destructors can easily involve much function-call overhead, but they are relatively rarely used, and may well be inlined anyway, depending on their complexity an the size/speed tradeoffs desired.
To get a good answer, ask a Smart Question. Similarly, if you want a bug fixed, write a Useful Bug Report. No TTDPatch crashlog? Then follow directions.
Projects: NFORenum (download) | PlaneSet (Website) | grfcodec (download) | grfdebug.log parser
Post Reply

Return to “OpenTTD Development”

Who is online

Users browsing this forum: Amazon [Bot] and 20 guests