0
\$\begingroup\$

I use a lot of path finding in my Monogame project which is taking a toll on the framerate, because in the worst case finding a path can take 200ms. So I looked into using Tasks to spread path finding computation over multiple frames and maybe even compute them simultaneously.

This required me to rewrite the path finding system into a version that I suspect is slower, and which definitely should use more memory. However! When I got it to work, the path finding now takes at most 8ms, and the memory usage according to Visual Studio has fallen by ~100MB.

That's nice of course, but just in the interest of understanding what's going on, can someone explain why this is?

The changes I made from before to after was basically to remove static path finding data, so that each task can have its own copy, and then I stuffed the path finding calls into a lambda and fed it to the Tasks.

Before:

while (requestQueue.Count > 0)
{
    PathRequest request = requestQueue.Dequeue();

    List<Tile> path = AStar.FindPathList(map, request.origin, request.target);
    if (path == null)
    {
        Debug.Warn("Unable to find path.");
    }
    else
    {
        path = AStar.SimplifyPath(path);
    }
}

After:

while (requestQueue.Count > 0)
{
    PathRequest request = requestQueue.Dequeue();

    Task pathTask = Task.Run(() =>
    {
        List<Tile> path = AStar.FindPathList(map, request.origin, request.target);
        if (path == null)
        {
            Debug.Warn("Unable to find path.");
        }
        else
        {
            path = AStar.SimplifyPath(path);
        }

        request.returnAction(path);
    });
}

How I make requests:

Tile origin = map.tiles.Get(/* ... */));
Tile target = map.tiles.Get(/* ... */));

pathManager.MakePathRequest(ReturnAction, origin, target);
agent.isAwaitingPath = true;

void ReturnAction ( List<Tile> path )
{
    agent.isAwaitingPath = false;

    if (path == null)
        agent.transform.WorldPosition = new Vector2(map.BorderSize * 4, map.BorderSize * 4);
    else
        agent.path = path;
}
\$\endgroup\$
4
  • \$\begingroup\$ We definitely need to see the code before and after. It would also be interesting to know how many cores you have. \$\endgroup\$ Commented Feb 22 at 13:57
  • \$\begingroup\$ @DMGregory Cool! 8 cores, and 16 logical processors \$\endgroup\$ Commented Feb 22 at 16:43
  • \$\begingroup\$ Well, the speed increase of 25x cannot be the result of parallelism. Could it be that the tasks were still running when you stopped the time? The thread that starts the tasks sees only the time it takes to setup and start the tasks, unless it awaits the results. \$\endgroup\$ Commented Feb 22 at 17:57
  • \$\begingroup\$ I create and stop the stopwatches inside the tasks - I just removed that code in the above for clarity \$\endgroup\$ Commented Feb 22 at 18:11

0

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.