Construction of my math vectors are really slow

Started by
17 comments, last by voguemaster 13 years, 6 months ago
Hello,

I've recently developed my own maths library for computer graphics. I have a very CPU intensive program that I used to do calculations component wise e.g:
GLdouble rx = particle[j].position[0] - particle.position[0];GLdouble ry = particle[j].position[0] - particle.position[0];GLdouble rz = particle[j].position[0] - particle.position[0];


However now that I've started using my own maths library my FPS goes from around 30 to around 11 FPS by changing the code above to:
Vector3d distance = particle[j].position - particle.position;


This makes me think that there's something wrong with my maths library. (The code above gets executed 1000^1000 times every iteration).

My vector constructors are:
// Constructs and sets the vector to (0, 0, 0)Vector3() : x(0), y(0), z(0) { }// Constructs and sets the vector to (vx, vy, vz)Vector3(T vx, T vy, T vz) : x(vx), y(vy), z(vz) { }// Constructs with data from another vectorVector3(const Vector3<T>& v) : x(v.x), y(v.y), z(v.z) { }


Equal and subtraction has the code:
Vector3<T> operator-(const Vector3<T>& v) const{	return Vector3<T>(x - v.x, y - v.y, z - v.z);}const Vector3<T>& operator=(const Vector3<T>& v){	x = v.x;	y = v.y;	z = v.z;	return *this;}


What can I do to fix my horrible performance dip?

Regards
Advertisement
Quote:Original post by GlassBil
What can I do to fix my horrible performance dip?

What compiler are you using? Do you have optimizations enabled? If you are using Visual C++ 2010, then in addition to regular optimizations, you may be able to enable SSE/SSE2 optimizations to your program.
Is this dip measured in release or debug builds? For a debug build, it makes perfect sense that you would see a performance drop, as you are creating a lot of temporary objects with the class based operators. In release mode, the compiler should optimize out the temporaries for you, yielding code more or less equivalent to your original approach.

If you are in release mode, try taking a look at the assembler output and seeing what the compiler is doing under the hood.
I would look at the assembly output of some performance-critical loop. There's probably something stupid going on.

Oh, and you are compiling with optimizations turned on, aren't you?

EDIT: Boy, am I slow.
Hi,

Another thing you can easily do to find out what the compiler is doing even in a
release optimized build is to have your ctor/dtor/assignment op. print some small
msg to a log file or the console.

Although this won't be good in terms of measuring the performance of the code, it
can tell you what the compiler is trying to do, even in release.

Now, without any kind of optimizations, the change of code is, roughly, a change
from substracting a set of 3 numbers and storing their result in 3 local varaibles, as opposed to the following operations with the vector class:

1. Creating a temp object to hold the result of the substraction
2. calling operator -
3. constructing a new object to hold the result, on the stack
4. calling operator =
5. destroying the temp object
6. once the result vector goes out of scope, it too will be destroyed.

Quite a bit for just one substract operation, right ? And we don't know anything
about how you called the code. If you're not careful there could be aliasing
issues and more...

A good compiler will optimize most of these problems, but apparently not all.
-----------------------------He moves in space with minimum waste and maximum joyGalactic Conflict demo reel -http://www.youtube.com/watch?v=hh8z5jdpfXY
Thanks for your responses. I've run it in Win7 with VC++ 2010 (debug mode) and with g++ in Centos with similar results.

I will try turning on optimization later today and get back to you with the results.
Couldn't the initializer list in the default constructor be the problem? Turning optimizations on, however, even with the initializer list should amlost eliminate or even completely remove the performance gap...
Using classes for such purposes is very nice and clean, but for time critical situations I'm always using inline functions or even macroses. As the others suggested, the point is to avoid creating temporally objects for such simple operations. It's true that the compiler would optimize the code if told so, but I suggest you to avoid the practice "do whatever you can imagine, the compiler should find about what you meant".
Quote:Original post by inprazia
Using classes for such purposes is very nice and clean, but for time critical situations I'm always using inline functions or even macroses. As the others suggested, the point is to avoid creating temporally objects for such simple operations. It's true that the compiler would optimize the code if told so, but I suggest you to avoid the practice "do whatever you can imagine, the compiler should find about what you meant".


Have you actually tested that?

I've gone through large amounts of code replacing things like A = B * a + C with inline functions... and found that the result (when compiler optimisations are enabled) is actually slower than the original. So you may have just been obfuscating your code with no benefit...
Hello!

I've now tried to run it with /O2 in VC++ 2010 in Release mode. This gives me 60 FPS and the old code (not using my maths library) gives me around 55 FPS. So it's actually faster now.

However my problem is that I can't get the optimization to work in Debug mode. When compiling I get the following error:
1>------ Build started: Project: Fluid, Configuration: Debug Win32 ------1>cl : Command line error D8016: '/ZI' and '/O2' command-line options are incompatible========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========


The default for "Debug Information Format" in Release mode is "Program Database (/Zi)", but when using that in debug mode I get:
1>------ Build started: Project: Fluid, Configuration: Debug Win32 ------1>cl : Command line error D8016: '/O2' and '/RTC1' command-line options are incompatible========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========


Is it even possible to do the optimization in Debug mode?

When it comes to compiling with g++ I guess I should use -O2 or similar flags?

Thanks again for all your help.

This topic is closed to new replies.

Advertisement