Archived

This topic is now archived and is closed to further replies.

Dwiel

static vars in common function slow it down?!

Recommended Posts

Hello, I was going through some of my time-sensitive code and found that when I added static to some of the variables my code got 2x slower!!! Here is the code:
	T PickRandomElement()
	{
		static float r = 0;
		static float temptot = 0;
		static int i = 0;

		r = randomx(total);
		temptot = 0;
		for(i = 0; i < numofnodes; ++i)
		{
			temptot += _set[i].prob;
			if(temptot >= r)
				return _set[i].element;
		}
/*		float r = randomx(total);
		float temptot = 0;
		for(int i = 0; i < numofnodes; ++i)
		{
			temptot += _set[i].prob;
			if(temptot >= r)
				return _set[i].element;
		}*/
		return T();
	}
That first block which is not commented out runs 25 million times in about 22 second... While the second part runs in just over 11. The biggest difference is the temptot variable going from static/non-static. The static version costs about 8~9 seconds! The same times are gotten when the static variables are no initialized in the top part, but are set before ever retrieved. Also, if I put the variables as member variables in the class, I get just under a second time speed increase over having them declared every fn call. THis is what you would expect. Does anyone have any ideas as to why this would be happening? Thanks! Dwiel
My home page!!!
Find out about my diy LCD projector and programming projects!

Share this post


Link to post
Share on other sites
If I had to guess, I''d say the problem was that the compiler can''t optimize away storage for the static into a register, combined with poor cache coherence.

Of course, it''s hard to say with knowing the complete types of all the variables, the contents of the randomx() function, etc. Was this a release or a debug build?

Share this post


Link to post
Share on other sites
This was a release build

the other functions I forgot are:

#define random()      ((float)rand() / (float)RAND_MAX)
#define randomx( x ) ((random()) * (x))


T is an integer in my app

Dwiel

P.S. This is the only function that is being called... Im timing it by executing it 25 million times. I doubt that it is the cache...

My home page!!!
Find out about my diy LCD projector and programming projects!


[edited by - Tazzel3d on April 3, 2004 11:09:19 PM]

Share this post


Link to post
Share on other sites
Making the variables static basically makes them global variables in the eyes of the compiler, which cuts down on a lot of the optimizations that it does.

The function you have doesn''t seem to require that the variables be static, so it''s best that they aren''t. Memory read/writes are expensive compared to when variables are held in registers.

There''s basically 2 uses for static variables, that I''ve seen, in functions that don''t require the value of the variable be kept for future function calls.

1) If you have a large buffer (ie a string), it can cost a lot to push all that memory on the stack.
2) If you have an array that you want to return a pointer to.

Keep in mind, if you return a pointer or reference to a static variable, unless you make a copy of it, that there is only ONE buffer. So if you call the function again and it changes the buffer, any prior pointer will see the changed information.

Share this post


Link to post
Share on other sites
I was under the impression that by declaring them static, the compiler wouldn''t have to allocate that space every function call. I completely forgot that the compiler smart enough to probobly never alloacte any space for those, but use registers... doh.

I think my misunderstanding came when I did this to a function which ''allocated'' a couple variables and di dvery little to them... by converting them to static, the compiler wouldn''t have to ''allocate'' them, but IIRC, I forgot to do this test in release mode, so it makes some sence.

Thanks for the help!

Its good to understand these kinds of things.

Dwiel

My home page!!!
Find out about my diy LCD projector and programming projects!

Share this post


Link to post
Share on other sites
Use a profiler to find actual slowdowns.

Making them static not only prevents optimizations but also opens the function up to subtle, hard to see bugs -- because they retain their old values and the function wasn''t written with this in mind.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Global varibles are allocated on the stack so it''s basically just an add esp, n and some memory initialization. With static variables you don''t have to initialize the memory every function call so that could make it faster in some circumstances.

Share this post


Link to post
Share on other sites
I''m not sure it makes a difference here but using statics inside your function will add (at least) one extra test (if the var has been initialised or not) at the beginning of each function (but 2x slower sounds over the top for such a small thing).

Share this post


Link to post
Share on other sites
quote:
Original post by amag
using statics inside your function will add (at least) one extra test (if the var has been initialised or not)

I did a small experiment which showed that that's not true. Here's the function I used:

float adder ()
{
static float f = 0.0f;
f += 0.1f;
return (f);
}

Which compiled to (cleaned up a bit):

__real@3dcccccd DD 03dcccccdr ; 0.1
{...}
f_adder DD 01H DUP (?)
{...}
adder PROC NEAR
fld DWORD PTR f_adder
fadd DWORD PTR __real@3dcccccd
fst DWORD PTR f_adder
ret 0
adder ENDP

Used VC6
EDIT: Leaving the '= 0.0f' initializer out changed nothing.


[edited by - nonpop on April 5, 2004 2:45:24 PM]

[edited by - nonpop on April 5, 2004 2:47:48 PM]

Share this post


Link to post
Share on other sites
Well, I guess the compiler may optimise this when dealing with builtin types. Not so with types with a ctor however. Anyway it seems that's a moot point in this case.

[edited by - amag on April 5, 2004 5:00:49 PM]

Share this post


Link to post
Share on other sites
Well that indeed seems to be the case (did another experiment)
And as the OP's function uses built-in types this is definitely not the cause of slow-downs (unless the compiler is broken )


[edited by - nonpop on April 5, 2004 5:52:47 PM]

Share this post


Link to post
Share on other sites
static, non static, volatile, non volatile, method or object instance variable performance strongly depends on the context and way of usage, there''s just some thumb rules but aren''t absolute.
To make it more funny, also depends on the compiler and compiler settings

-Mat

Share this post


Link to post
Share on other sites