Why is this code so slow?

Started by
22 comments, last by Andrew Russell 18 years, 11 months ago
Ok... I'm calling the following dot product function during rendering and it's slowing everything down like crazy for some reason: float Dot(POINT3D Vector1, POINT3D Vector2) { return (Vector1.x * Vector2.x) + (Vector1.y * Vector2.y) + (Vector1.z * Vector2.z); } The thing is... I tried doing the dot product manually in the code to see what was up and there was no slowdown: (Vertex[0].x * Vertex[1].x) + (Vertex[0].y * Vertex[1].y) + (Vertex[0].z * Vertex[1].z); So, it's gotta be the function, right? Or possibly a memory thing? I'm confused...
Advertisement
you might want to make those parameters const references and inline the function..
what does that do exactly?
hmm.. really hard to say without knowing details like how often it's being called
But it definately needs inlining.
just pop the word inline in front of the function definition & instead of jumping to the function (& doing the memory shuffling required for that) it will insert the code directly where it's called (when possible). Basically it's an optimisation keyword for functions that are small yet called v. often where speed is required.
This is the perfect substitute. In effect it will do more-or-less exactly what you did when it compiles - just insert the code itself
Give that a go & see how it affects your speeds
_______________________________ ________ _____ ___ __ _`By offloading cognitive load to the computer, programmers are able to design more elegant systems' - Unununium OS regarding Python
Also, if you are using C, you should pass references instead of objects. So your function should be defined:

float Dot(const POINT3D* V1, const POINT3D* V2)
{
return V1->x * V2->x + V1->y * V2->y + V1->z * V2->z;
}

Using inline is not the best solution unless you are using this function heavilly.

Luck!
Guimo
I hate to be a bore asking the usual questions... But are you sure that is the offending code? i.e. Have you checked it with a profiler?

I have spent long hours speeding up 'slow' code which turned out to be fine when I found out that something else had been causing the problem!

Mark Coleman
Quote:Original post by Drythe
Ok... I'm calling the following dot product function during rendering and it's slowing everything down like crazy for some reason:

float Dot(POINT3D Vector1, POINT3D Vector2)
{

return (Vector1.x * Vector2.x) +
(Vector1.y * Vector2.y) +
(Vector1.z * Vector2.z);

}


The thing is... I tried doing the dot product manually in the code to see what was up and there was no slowdown:

(Vertex[0].x * Vertex[1].x) + (Vertex[0].y * Vertex[1].y) + (Vertex[0].z * Vertex[1].z);

So, it's gotta be the function, right? Or possibly a memory thing? I'm confused...



The reason why it is so slow is that you are passing two POINT3D objects by value. Every time you call this function it is doing two memcopies of your POINT3D structures. You probably want to rewrite your function like this:

inline float Dot(const POINT3D& Vector1, const POINT3D& Vector2){	return (Vector1.x * Vector2.x) + 	   (Vector1.y * Vector2.y) + 		   (Vector1.z * Vector2.z);}


the ampersand tells the compiler to pass the objects by REFERENCE, instead of by value. Instead of doing a mempcy of the POINT3D structure, it is doing a copy of a POINTER to the POINT3D structure, which is much smaller. The const keyword simply implies that the object's value won't be and can't be changed inside the function. I would also make this function inline since three multiples and adds isn't going to generate a large amount of code, and making it inline asks yours compiler to not just place the code in your function, instead of making it jump to another function ( Dot() ) to do the math.

- S
ah, you guys are awesome...

inline did the trick. I'm gonna use it with all of the vector functions now (I'm gonna get like 500% speed increase judging from the dot function...).

I also changed the POINT3D to reference... although I don't quite understand the distinction between defining it pointer(*) or reference(&). I guess I'll read up on that.

Thanks a lot for the help;)
The only difference in the behavior of a reference and a pointer is that a reference cannot be null. Everything else is just syntax. In your case, passing by reference means the points don't get copied, but instead you get a level of indirection. Inlining it makes that argument rather pointless though, as the parameters are never actually 'passed'.
I'm not totally sure, but inline I believe simply copies the code wherever the function call is, instead of calling the function. So everytime you put Dot(Vector1, Vector2); in your program, when compiled it actually inserts the code:

return (Vector1.x * Vector2.x) +
(Vector1.y * Vector2.y) +
(Vector1.z * Vector2.z);

in place of the the function call. So, in that respect inlining is great, but it also increases the size of your executable, because instead of just having the code:

float Dot(POINT3D Vector1, POINT3D Vector2)
{

return (Vector1.x * Vector2.x) +
(Vector1.y * Vector2.y) +
(Vector1.z * Vector2.z);

}

somewhere once in the exe, it actually puts it in at every function call that is made. So if you use inlining on everything, your exe might end up quite a bit larger than without them. It's the whole speed vs size thing, which back in the day was a problem, but as hard drive space gets cheaper and the internet gets faster, having an exe that's a few megabytes larger is probably worth it.

Correct me if I'm wrong please somebody.
-Dan- Can't never could do anything | DansKingdom.com | Dynamic Particle System Framework for XNA

This topic is closed to new replies.

Advertisement