HiveBrain v1.2.0
Get Started
← Back to all entries
patterncppMinor

Calculating angles and distances

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
anddistancescalculatingangles

Problem

I am running a simulation with 250 interacting agents and have a few functions that are called over and over again. Even with precomputing all distances between agents before the N2 (250x250) interaction loop, my simulation is still very slow. Are there any C++ optimization tricks that I could use to speed these up?

This is the most-used function in my simulation. It calculates the distance2 between two agents in a continuous space. I have a feeling there isn't much that can be done to further optimize this, but you guys have surprised me with some tricks before:

double tGame::calcDistanceSquared(double fromX, double fromY, double toX, double toY)
{
    double diffX = fromX - toX;
    double diffY = fromY - toY;

    return ( diffX * diffX ) + ( diffY * diffY );
}


Here's another expensive function in my simulation. It calculates the angle from one agent to another agent relative to the 'from' agent's heading. As you can see, I already did a little precomputing with the atan2() function (and that DOES speed things up a bit, despite what I've read in other posts).

double tGame::calcAngle(double fromX, double fromY, double fromAngle, double toX, double toY)
{
    double Ux = 0.0, Uy = 0.0, Vx = 0.0, Vy = 0.0;

    Ux = (toX - fromX);
    Uy = (toY - fromY);

    Vx = cosLookup[(int)fromAngle];
    Vy = sinLookup[(int)fromAngle];

    int firstTerm = (int)((Ux * Vy) - (Uy * Vx));
    int secondTerm = (int)((Ux * Vx) + (Uy * Vy));

    if (fabs(firstTerm) < 1000 && fabs(secondTerm) < 1000)
    {
        return atan2Lookup[firstTerm + 1000][secondTerm + 1000];
    }

    else
    {
        return atan2(firstTerm, secondTerm) * 180.0 / cPI;
    }
}


Finally, here's the monster function that uses the calcDistanceSquared() function so much. This is run every simulation time step, and there's 2,000 time steps per simulation (and MANY simulations). The most expensive part is the calcDistanceSquared() in the N2 loop.

```
void tGame::recalcPredAndPreyD

Solution

It looks good to me. I would change

if (!preyDead[i])
    {


To

if (preyDead[i])
            continue;


Just so its less nested. Same with preyDead[j]. But everything looks fine to me.
A tip I once saw on SO is, if your list order doesn't matter you can sort the preyDead so all the dead would be at the beginning or end and that will help branch prediction. However thats assuming its not really expensive to sort it and that its a very erratic bool and it isnt true/false 90% of the time already.

Thats a uber optimize that may not help, it shouldn't be done less you really really want to

Code Snippets

if (!preyDead[i])
    {
if (preyDead[i])
            continue;

Context

StackExchange Code Review Q#20466, answer score: 3

Revisions (0)

No revisions yet.