#### Archived

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

# Can anyone help optimise this code?

This topic is 6945 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

After a complete lack of responce from my vectors post, I managed to work out the routing myself. however, it seems over complicated and slow. I was wondering if anyone has any ideas about how to speed it up? the code concerns moving one vertex to another, but making sure that destination is reached at the same time on all 3 axis. there is a maximum speed that the vertex can move, but it can move slower if needed. the code is below. CVector __VECTOR; CVector __TMPVECTOR; CVector CreateVector(CVertex Current, CVertex Destination, int Speed) { __VECTOR.X = Current.X - Destination.X; __VECTOR.Y = Current.Y - Destination.Y; __VECTOR.Z = Current.Z - Destination.Z; if(__VECTOR.X < 0) __TMPVECTOR.X = VECTOR.X * -1; if(__VECTOR.Y < 0) __TMPVECTOR.Y = VECTOR.Y * -1; if(__VECTOR.Z < 0) __TMPVECTOR.Z = VECTOR.Z * -1; float LargeVec; if(__TMPVECTOR.X >= __TMPVECTOR.Y) { if(__TMPVECTOR.X >= __TMPVECTOR.Z) { LargeVec = __TMPVECTOR.X; } else { LargeVec = __TMPVECTOR.Z; } } else { if(__TMPVECTOR.Y >= __TMPVECTOR.Z) { LargeVec = __TMPVECTOR.Y; } else { LargeVec = __TMPVECTOR.Z; } } int Frames; Frames = RoundUpFloatToInt(LargeVec) / Speed; // gives the number of frames __VECTOR.X = __VECTOR.X / Frames; __VECTOR.Y = __VECTOR.Y / Frames; __VECTOR.Z = __VECTOR.Z / Frames; __VECTOR.Life = Frames; return __VECTOR; } i know the board is gonna make a complete hash of the code, but i think the idea is clear. i also need to know how to rount up a float to the next integer, e.g. 4.2 goes to 5, 1.00000000000000000000000001 goes to 2. any help appriciated MENTAL

##### Share on other sites
Hi,

You're not initializing __TMPVECTOR.? for positive VECTOR.? values.

I *think* the following will work (and fix the above bug I mentioned), but I'm not sure if it's a good idea, nor what it will do for performance.

You might try changing:

if(__VECTOR.X < 0)
__TMPVECTOR.X = VECTOR.X * -1;

if(__VECTOR.Y < 0)
__TMPVECTOR.Y = VECTOR.Y * -1;

if(__VECTOR.Z < 0)
__TMPVECTOR.Z = VECTOR.Z * -1;

to (assuming you're working with floats):

__TMPVECTOR.X = VECTOR.X & 0x7fffffff; // force signbits positive
__TMPVECTOR.Y = VECTOR.Y & 0x7fffffff;
__TMPVECTOR.Z = VECTOR.Z & 0x7fffffff;

You can replace all that code that finds the largest of the three by:

float LargeVec = MAX(MAX(__TMPVECTOR.X, __TMPVECTOR.Y), __TMPVECTOR.Z); // but this is probably essentially the same as what you're doing already

I'm not sure the best way to round up a float the way you want. Simply adding 1.0 will usually work, except when the value is an whole number.

Hope this helps a bit. BTW, your code looks like it wouldn't be that slow already. Have you tried timing it or anything yet?

aig

Edited by - An Irritable Gent on 4/16/00 12:22:16 PM

##### Share on other sites
//RoundAFloatUpToNearestInt:
float f = someValue;
int i = static_cast< int > (f + 1.0f);
// or using C casts;
int i = (float) (f + 1.0f);

Jaap Suter

##### Share on other sites
quote:
Original post by s9801758

//RoundAFloatUpToNearestInt:
float f = someValue;
int i = static_cast< int > (f + 1.0f);
// or using C casts;
int i = (float) (f + 1.0f);

Jaap Suter

Actually, it should be:

int i = static_cast(f + 0.5f);

As for the original code, you''re making things WAY to complicated. First, you only need to calculate the difference vector, scaled by speed, from the current position to the destination position. You can calculate the frames by taking any non-zero component of the difference vector and dividing that by the scaled vector. The code is trivial, and if you can''t figure out how to do it yourself, learn some linear algebra.

MSN

##### Share on other sites
The easiest way to optimize this would be to take out the multiplication and division so here is what I would do...

if(__VECTOR.X < 0)
__TMPVECTOR.X = -VECTOR.X;

if(__VECTOR.Y < 0)
__TMPVECTOR.Y = -VECTOR.Y;

if(__VECTOR.Z < 0)
__TMPVECTOR.Z = -VECTOR.Z;

As for the division, I''d probably do some bitshifting.

Now onto the rounding:

float f,f2;
int final;

f2= (f-(int)f);
if(f2>=0.5)
final=(int)f+1;
else
final=(int)f;

##### Share on other sites
The "rounding" question the original poster had was not about true rounding, but about bumping up to the next whole number, ie. 1.00001 would bump up to 2.

aig

##### Share on other sites
Try this code (available for free from Nvidia''s website, along with some other fast floating point code)

__forceinline void FloatToInt(int *int_pointer, float f)
{
__asm fld f
__asm mov edx,int_pointer
__asm FRNDINT
__asm fistp dword ptr [edx];

}

Also, if you want to see if code can be optimized, may I suggest making a post like "I''ve optimized this code, I don''t think it can get any more than 50% faster, I challenge anyone here to try to beat that." You''ll probably get a lot more replies.

##### Share on other sites
quote:
Original post by mhkrause
Also, if you want to see if code can be optimized, may I suggest making a post like "I''ve optimized this code, I don''t think it can get any more than 50% faster, I challenge anyone here to try to beat that." You''ll probably get a lot more replies.

Alright, a challenge it is then!

Renaming everything to be a little more semantically accurate, as well as removing the frames member, since it''s just ceil( length( vel )/speed ). Note: This is not optimized for any sort of SIMD instructions.

CVector GetVelocityVector( const CVector& pos, const CVector& dest, int Speed )
{
CVector vel;

vel.x = dest.x-pos.x;
vel.y = dest.y-pos.y;
vel.z = dest.z-pos.z;

float invspd = 1.0f/Speed;

vel.x*=invspd; vel.y*=invspd; vel.z*=invspd;

return vel;
}

MENTAL: What exactly do you want this function to do? Do you want the velocity to move the position to destination in a set number of frames, or at a specific speed? Because otherwise this problem is deceptively easy, with a proper background in numerical methods.

MSN

##### Share on other sites
Thanks for heling out everyone!

msn12b: i want it to move using the required velocity or less. The number of frames is in so i know when to stop the vector. however, the vertex MUST meet at the destination at the same time on all 3 axis or else it will look funny.

the frame number is included because it is decresed on each cycle of the game loop, and when it''s zero, the vector is no longer applied. it is much simpler (and probably faster) to calculate it once, instead of calculating "ceil( length( vel )/speed )" every frame.

could you please tell me how your code works, as i''m finding it slightly confusing

aig: thanks for the signbit code. i never knew it could be done this way!

mhkrause: wooo, optimizations a go-go! does this code work on any PC, or only one with a NVidia graphics card (i''m useless when it comes to complicated assembler).

as for the competition, i''m gonna try out all of these improvements, and then post it with the "I can get the code working 50% faster...". good idea

MENTAL

##### Share on other sites
quote:
Original post by MENTAL
msn12b: i want it to move using the required velocity or less. The number of frames is in so i know when to stop the vector. however, the vertex MUST meet at the destination at the same time on all 3 axis or else it will look funny.

The code takes the displacement vector, divides by the speed, and stores the resultant vector as the velocity vector.

if( vel.x!= 0 )
{
vel.Frames = ceil( (dest.x-pos.x)/vel.x );
}
else if( vel.y!= 0 )
{
vel.Frames = ceil( (dest.y-pos.y)/vel.y );
}
else if( vel.z!= 0 )
{
vel.Frames = ceil( (dest.z-pos.z)/vel.z );
}
else
{
vel.Frames = 0;
}

MSN

• 10
• 33
• 29
• 9
• 15