Speed/efficiency of pointer dereferencing

Started by
7 comments, last by Foopy 24 years, 6 months ago
Un-optimized, the dPointer method is faster, because it doesn't dereference as many times. But most compilers will pick up on a->b->c->d if used more than once in a row, and optimize it, so I wouldn't worry too much (I also wouldn't write code that dereferences that much, but that's just me!)

foofightr

Advertisement
I came across the same problem, my game often uses constructs like this
Engine->Renderer->FindEntity(id)->Remove();

Well, a class has to store its pointers (and variables of course). Modern compilers like VC align these to 16 (or even up to 128) Bytes
That's one point which determines speed ... though you cannot change anything about it ...

VC seems to even put those adresses in processor registers sometimes, so your first example would even be faster than the second...
If you're using DJGPP or VC Standard (Pro has better optimizing), you should use the second approach, perhaps together with the register keyword, if your function doesn't do heavy calculations.

-Markus-

Professional C++ and .NET developer trying to break into indie game development.
Follow my progress: http://blog.nuclex-games.com/ or Twitter - Topics: Ogre3D, Blender, game architecture tips & code snippets.
Generally, with a decent compiler, approach 2 is never going to generate worse code than approach 1. In debug builds, with optimizations off, approach 1 may generate worse code than approach 2.

From a legibility and maintenence standpoint, I think approach 2 is a winner also. Say someday you change the heirarchy so the location of D is moved. With approach 1, you have to change 3 lines of code. With approach 2, you only have to change the one line.

------------------
-vince


-vince


Just one thing: the "register" keyword is a no-no. You might end up preventing the compiler from doing an optimization because you are trying to enforce a particular use of a register. If you want to control how registers are used, code in asm.

(I guess the general rule is to either leave code-level optimization (as opposed to design optimization) to the compiler or do it yourself entirely ).

/Niels

<b>/NJ</b>
Thanks for the replies, guys. The reason my pointer heirarchies go this deep is because I'm trying to make a cross-platform 2D API with pluggable device drivers, so I'm structuring the platform framework in a somewhat similar fashion to Java's java.System package. In my framework, the SystemDriver class is a class that contains some OS-specific member functions (like one that performs OS-level event handling), and it's also a container class that contains instances of VideoDriver, AudioDriver, KeyboardDriver, etc classes which give an abstract interface to the given device. An implemented descendant of the given abstract base class constitutes a device driver (for example, DirectXKeyboardDriver could be a descendant of KeyboardDriver), and the only global variable that the game logic accesses is an instance of SystemDriver called System. Thus in the actual game logic, if someone wanted to get a character from the keyboard, they'd do something similar to

System->keyboard->readkey();

Specific driver instances would be loaded at the beginning of program execution. This framework would result in the game logic being entirely platform-independent, and the only part of the actual game code that should be non-platform-dependent would be the device driver implementations and possibly a configuration screen in the game.

Does this sound like a good framework, or would the virtual functions or something else slow down the game a great deal? Andre Lamothe says not to use "layers of software" in games, but I'm not sure if this system constitutes as the kind of "layer of software" that a game programmer should avoid. But isn't this basically how games like Unreal and Half-life (which have pluggable device drivers) work? It also seems like the easiest way to make a framework that's cross-platform, and one in which you can change drivers on-the-fly.

You mentioned Java yourself, why not go for Java as the "game implementation language" it provides a lot of the abstractions you are looking to create (and it's a far better language than C++)... You could still create custom platform dependent DLLs for the really hardcore stuff (or simply wrap the DirectX Java implementation in a thin Java layer)...

As for performance, Java is really quick, and getting faster with each new revision of the run-time systems.

The fact that JavaRTs can perform run-time code optimization means they are capable of adapting the code to the EXACT hardware on which it is running - Something you can't even hope for with C++... I wouldn't be suprised to see bechmarks in the not so distant future where Java outperformed C++.

/Niels

<b>/NJ</b>
Yes, actually I am planning on doing this, but I don't want to mess with the intricacies of JNI right now (also, supposedly JNI and the Invocation API are very unstable on non-win32 platforms, which is why Quake III doesn't use it)... But I'm trying to design the my API so that I can easily write a wrapper that wraps the functions of my API for Java to use; but I want to start out with C++ because although the language isn't nearly as nice and organized as Java, it's more supported on more platforms (how ironic) and I don't have to deal with any JNI interfacing. Someday I'd like to port the API to Java, though, because Java is so much nicer to program in than C++.
Hello,

I've got a question about the efficiency of dereferencing pointers (well, I think "dereferencing" is the word I'm looking for). Here's my dilemma:

Say I've got four classes called A, B, C, and D. An instance of B called "b" is contained as a public member of A, an instance of C called "c" is contained in B, and so on. Let myMethod1..3 be member functions of the D class, and let a be an instance of the A class.

Now take this chunk of code:

a->b->c->d->myMethod1
a->b->c->d->myMethod2
a->b->c->d->myMethod3

My question is, will there be any speed difference between this code and manually caching the location of a->b->c->d beforehand, as follows:

D *dPointer = a->b->c->d

dPointer->myMethod1
dPointer->myMethod2
dPointer->myMethod3

So basically I'm wondering if the compiled program has to re-compute the location of a->b->c->d (by dereferencing a, then dereferencing b, then c, and then d) or not. Any help on this issue would be greatly appreciated.

We use Java exactly as described above and have had very pleasing results. All of our game logic is written in Java with the hardcore engine routines in a native DLL, using JNI as the layer inbetween.

Currently we support Win95/98 and Mac - we haven't had any problems that I know of with JNI on those two platforms. Dunno about any others...

Using your current method you can always add the JNI layer above your current C++ abstraction layer - this has some benefits. For instance you can write pure C++ test apps for the core engine. Debugging the native routines is a lot easier in an all-native environment.

------------------
-vince


-vince


This topic is closed to new replies.

Advertisement