Advertisement

Allocating memory, how fast is it?

Started by May 29, 2004 05:19 AM
12 comments, last by _the_phantom_ 20 years, 5 months ago
Quote: Original post by schue
I would not recommend the usage of global variables at all, only when its absolutly no other way. I consider massive use of global variables as bad programming, especially if you program c++.

While it might not seem to be wrong to use them in small programs, once your project gets bigger and more complex, global variables can become a source of ugly and hard to debug problems. Sooner or later you will lose track about all the places where you used that special variable.


I totally disagree.
Using global variables makes the debuging process FAR easier, as global variables are visible no matter where the program crashed, while the local variables are visible only in the function the program crashed.
Quote: Original post by _the_phantom_

Quote: Original post by Oxyd

The variables (stack ones) are created when you enter the scope. In C++ you may declare them wherever you want in the scope, but they exist since the entry of the scope:


Errm, I think you'll find this is horribly horribly wrong.
C++ doesnt construct a varible until it is used, which is a good plan as it can delay costly object construction until such time as it is needed, instead of constucting all the objects up front and having to destory them anyway even if you never use them.
Thus why you should delay declaring and constucting objects for as long as possible in C++ (iirc its one of the tips in either Effective C++ or More Effective C++).

With regards to the APs comment:
Objects are constucted/destory'd apon entry/exit of blocks in the majority of cases, namely things which are non-trival. For example you might be using a class in a loop which is allocated and adjusted as such when the loop finished the object has to be destoryed correctly and remade at the start of the next loop.
Granted, for things like int, floats, chars etc if MIGHT be able to get around it, depending on how its used, but for more complex objects the scopeing rules apply.


A few weeks ago I decided to take a look at the ASM code of a simple C++ function (Reading an article about buffer overflow techniques), and I THOUGHT I saw everything on the stack created at function start. I'm not sure though (I'm no ASM guru, far from that).

But to comment on the initial post, tossing stuff on the stack is the fastest way. Inside your function do a "double[11]" and it will be put on the stack. This will often be in cached memory if I'm correct. If you make it global it will be put in heap memory, meaning that if you're unlucky it's not cached. Creating it with new is slowest, because at that point you're going to ask your OS for some memory. And you also need to free that memory again, so you're going to do a lot of work.

But I want to ask you this, what are you optimising? You're talking about differences in memory access speeds here.
If you're optimising some commonly used code (ie: often used maths code like cos/sin/vector stuff) then OK. But if this is about object management like loading textures or adding players it's a bit of an useless optimisation because it will be rarely used anyway (compared to your maths code for example).
STOP THE PLANET!! I WANT TO GET OFF!!
Advertisement
I have to agree with the above post. Why are you worrying about the speed of an array allocation? Unless you've reached the end of your project and have profiled it and found this to be a bottleneck then you don't need to consider optimising it. Premature optimisation is a very inefficient coding practice.

That being said I would recommend you use the following depending on situation:
Global variable: NEVER!!!! Global variables are evil (OK, saying they're evil is going a bit far, but I'm trying to make a point).
Stack based: For small fixed- and known-sized arrays only required in the current function.
Dynamically allocated: Never, see below.
std::deque or std::vector: All other cases. Deque's often have better performance when the array grows and shrinks because the memory does not have to be contiguous.

Enigma
Quote: Original post by Tree Penguin
Quote: Original post by _the_phantom_
C++ doesnt construct a varible until it is used

If that's true i really really DON'T get the speed difference between the examples i gave above.


the speed difference you gave is pretty much a non-issue anyway (3fps isnt much, it would probably be covered by the error level with timing).

I've got a copy of Effective C++ infront of me now and, Item 32 on pg 135 "Postpone varible definitions as long as possible', says
Quote:
Remember that when you define a varible of a type with a constructor or deconstructor, you incur the cost of constrution when the control reaches the variable's definitions, and you incur the cost of destruction when the variable goes out of scope. This means there is a cost associated with unused varibles, so you want to avoid them whenever you can.


now, for something like an int the cost of construction on the stack is pretty much a case of sub 1 from the stack pointer and assign the point on the stack with the value given, deconstruction is just a case of adding back 1 to the stack pointer to remove the variable from scope. This is trivial work and shouldnt really be worried about for the most part its larger objects where things really make a difference which have complex (de)constructors.

As to the speed difference between code, thats as much down to the compiler, the settings used and even how the varible is used, as anything else.
In the for-loop example given the varaible 'i' in the first block of code is allocated, assigned and then deallocated when 'i' goes out of scope at the end of the loop.
The second code block allocated 'i', enters the loop scope, runs the loop and exits leaving the 'i' allocated on the stack (until such time it goes out of scope).
While the first version does a little more work you should pretty much ALWAYS use that version to prevent scoping issues with loop varibles.
for example:
- You declare 'i' at the top of the function or just outside the first loop it is used.
- you use 'i' in that loop
- you then use 'i' for something else later on without clearing it, this could lead to a bug which could take a while to track down, where as declaring it in the scope of the for loop instead throws a compiler error and makes you fix the code there and then.
You will see alot of code which uses the second way, this is because until recently the VC++ compile was broken and didnt respect the scoping rules correctly.

This topic is closed to new replies.

Advertisement