Custom Primatives... faster?

KiroNeem
Unregistered
 
Post: #1
I have looked at code here and there, and I have notices a few differences with how people program geometric primitives. The particular thing that I noticed was custom primitives. Sometimes with structs, arrays, or even classes to represent paired data like 2D and 3D points.

Although I'm unsure of the purpose of this. Is code using custom geometric primitives used for speed, or is it just organization of code?
Quote this message in a reply
Moderator
Posts: 1,140
Joined: 2005.07
Post: #2
If you're talking about structs or classes, those aren't custom primitives, but custom types. Primitives would be things such as int and double. I'd say that custom primitives would be typedefed primitives.

As for using custom data types, I'd say it's more about the organization. I doubt there would be much speed difference between accessing a member of a struct and accessing a member of an array. (it's more or less the same thing)
Quote this message in a reply
KiroNeem
Unregistered
 
Post: #3
I do admit that there are many things you can do with those custom types that can speed production along. For example addition, subtraction, dot-products, cross-products, etc. I guess the only reason I have not done them is I'm just worried about speed, since variables like 3D points will be thrown around everywhere in my programs.
Quote this message in a reply
KiroNeem
Unregistered
 
Post: #4
So I decided to build a simple speed tester to see the speeds for myself, and here are the results I was given.

Each operation was performed 100,000,000 times
Each operation takes three int[3] and adds two of them to the other
EX:
three[0] = one[0] + two[0];
three[1] = one[1] + two[1];
three[2] = one[2] + two[2];


CPP class operator: 2.4 Seconds
CPP class with c function: 1.6 Seconds
Writing directly in C: 0.1 Seconds
C function: 0.8 Seconds

I then went ahead and added inline to all the functions, although for some reason I got slower times Huh
Quote this message in a reply
Member
Posts: 198
Joined: 2005.01
Post: #5
It could be because in a lot of cases memory footprint is more useful than inlining. That's why Xcode defaults to -Os on PPC.

There are a lot of variables there in your tests. Any compiler worth its salt should be able to take things like:

Code:
struct Foo {
   int x, y, z;
   Foo operator+( const Foo & o ) const {
      Foo r;
      r.x = x + o.x;
      r.y = y + o.y;
      r.z = z + o.z;
      return r;
   }
};

Foo a, b;
Foo c(a + b);

And turn it into pretty much the equivalent of the C code. IIRC there was some debate a while back at my job about using the constructor like that at the end vs using the implicit operator= ... too arcane for me to remember this early in the morning. Smile But as you can see it's a very nuanced issue.

Cryptic Allusion Games / Cryptic Allusion, LLC
http://www.cagames.com/
Quote this message in a reply
DoG
Moderator
Posts: 869
Joined: 2003.01
Post: #6
gcc does fairly well with inlined C++ and C. I usually get very acceptable speeds by making non-virtual, mostly inlined classes for geometric primitives such as matrices and vectors. The only way to get even faster is to use streaming together with altivec.

In my experience, inlined C++ is not slower than inlined C, usually.
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #7
In fact, until GCC 3.3, it was usually faster Smile
Quote this message in a reply
KiroNeem
Unregistered
 
Post: #8
Actually I'm surprised they do not go faster when I have used them. Don't they insert it's code into the place of the function call during compiling?
Quote this message in a reply
Moderator
Posts: 771
Joined: 2003.04
Post: #9
KiroNeem Wrote:Actually I'm surprised they do not go faster when I have used them. Don't they insert it's code into the place of the function call during compiling?

If you are trying to use inline with C++ methods, then it won't work. You need to put the methods you want to inline directly in the header for the compiler to inline them, like this:

Code:
/*
*  CVector3.h
*  Created by Ignacio on Wed Jul 23 2003.
*/

#ifndef __CVECTOR3_H__
#define __CVECTOR3_H__

#include <cmath>

#ifndef PI
#define PI 3.14159265359f
#endif

class CVector3
{
public:
    float x;
    float y;
    float z;

    CVector3()                                    { x = 0.0f; y = 0.0f; z = 0.0f; };
    CVector3(float X, float Y, float Z)            { x = X; y = Y; z = Z; };
    CVector3 operator+(const CVector3& v) const    { return CVector3(v.x + x, v.y + y, v.z + z); };
    CVector3 operator-(const CVector3& v) const    { return CVector3(x - v.x, y - v.y, z - v.z); };
    CVector3 operator*(float num) const            { return CVector3(x * num, y * num, z * num); };
    CVector3 operator/(float num) const            { float ratio = 1.0f/num; return CVector3(x * ratio, y * ratio, z * ratio); };
    void operator=(const CVector3& v)            { x = v.x; y = v.y; z = v.z; };
    void operator+=(const CVector3& v)            { x += v.x; y += v.y; z += v.z; };
    void operator-=(const CVector3& v)            { x -= v.x; y -= v.y; z -= v.z; };
    void operator*=(float num)                    { x *= num; y *= num; z *= num; };
    void operator/=(float num)                    { float ratio = 1.0f/num; x *= ratio; y *= ratio; z *= ratio; };
    float    Magnitude() const                    { return sqrt(x*x + y*y + z*z); };
    float    Magnitude2() const                    { return (x*x + y*y + z*z); };
    void     Normalize()                         { float ratio = 1.0f/Magnitude(); x *= ratio; y *= ratio; z *= ratio; };
    CVector3 Normalized() const                    { float ratio = 1.0f/Magnitude(); return CVector3(x*ratio,y*ratio,z*ratio); };
    float    Dot(const CVector3& v) const        { return (x*v.x + y*v.y + z*v.z); };
    float    Angle(const CVector3& v) const;
    float    AngleX() const                        { return atan2(-y,x); };
    float    AngleZ() const                        { return atan2(-y,z); };
    float    AngleY() const                        { return atan2(-x,z); };
    CVector3 Cross(const CVector3& v) const        { return CVector3((y*v.z - z*v.y),(z*v.x - x*v.z),(x*v.y - y*v.x)); };
    void     MutateBy(const CVector3& v);
    CVector3 MutatedBy(const CVector3& v) const;
    void     Print() const;
    void     Print(const char *objectName) const;
};

In this example 3D vector class, every method is inlined, except for Angle, MutateBy, MutatedBy & both Prints, which have their code written as usual on the .cpp file. Note that the "inline" keyword is not even necessary.
Quote this message in a reply
DoG
Moderator
Posts: 869
Joined: 2003.01
Post: #10
Actually, inline with C++ has the same restrictions as inline in C. The function definition must be included for it to work. Additionally, virtual functions cannot be inlined, as the implementation to call is decided at runtime.

When I said inlined C++ is just as fast, I was comparing it to inlined C.
Quote this message in a reply
zKing
Unregistered
 
Post: #11
Note the inline is just a 'suggestion' to the compiler, it can pick and choose what to do case by case (including ignoring all your suggestions). On top of this, depending on your compiler optimization settings it may inline functions for speed that you didn't mark as inline. Basically its all _extremely_ compiler dependant.

Secondly, inlining can make your code slower... because it makes it larger. Why? If your code begins to grow in size such that it no longer fits nicely into the CPU caches or causes some boundry case memory paging.

I think this belongs under...
"Premature optimization is the root of all evil." - Donald Knuth

I'd also add that optimization without first measuring and then making a goal for what metrics you want to hit is pointless. Or to put it another way:

1) Build it as simple as possible so that it is bug free and it works correctly.

2) Measure its performance and determine what needs to be faster and where you can realistically improve it.

3) Make very targeted fixes to improve performance. Remember that design/algorithm changes almost always have _far_ more performance effect than one line 'speed ups'.

Oh and you want to know the magic wand for solving performance problems, schedule problems, man power problems, budget problems... just about every software development problem?:
Cut features.

In my experience this is the most consistently succesful solution to a project that is out of control in one way or another.
Quote this message in a reply
Moderator
Posts: 1,140
Joined: 2005.07
Post: #12
Assuming you have optimizations enabled, the compiler might inline for you, which will make it a moot point. Also, you can't inline with a loop. (I'm sure you can't with recursion, either)
Quote this message in a reply
DoG
Moderator
Posts: 869
Joined: 2003.01
Post: #13
Functions in loops do get inlined, but loop unrolling is another issue. Recursion can be inlined up to a certain extent.

How inline behaves with gcc at least is well documented. See http://developer.apple.com/documentation...nline.html

Nowadays, one can expect sane behaviour from most compilers.

Unless you tell gcc to do otherwise, and honouring the other requirements for a function to be inlined, inline behaves as expected. Obviously, inline is an optimisation, so optimisations have to be turned on.

Speaking of math primitives, it doesn't take much brains to inline a function that adds a few numbers if things get slow. A function call adding a few dozen instructions takes several times longer to execute than the function body itself. Usual optimisation steps apply, eg profile first, but this is really one of the prime cases inlining was meant be used for.
Quote this message in a reply
Moderator
Posts: 1,140
Joined: 2005.07
Post: #14
DoG Wrote:Functions in loops do get inlined
Yes, but functions that contain loops can't be inlined. Rasp
Quote this message in a reply
DoG
Moderator
Posts: 869
Joined: 2003.01
Post: #15
akb825 Wrote:Yes, but functions that contain loops can't be inlined. Rasp

That is nonsense. RTM.
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  Parsing from a string to something faster? Madrayken 3 3,145 Aug 10, 2009 03:32 PM
Last Post: smasher
  Faster And Faster! Coin 2 3,431 Feb 24, 2005 10:42 PM
Last Post: Coin
  Objective-C: drawing a custom class to a custom view GryphonClaw 1 4,092 Dec 10, 2004 03:32 AM
Last Post: GryphonClaw