timing experiment: async vs sync line traces

I noticed there is both a synchronous and asynchronous line trace interface. I’ve just tried out both.

Of course the details will depend on your scene, but here’s an experiment I did with line traces to a 505x505 landscape actor object. The async interface has two sides: launching the request, and querying the result during the next frame. I’ve also put a total column that’s the total time for the request and the query.

For my scene there seems to be a small win on the game thread for the async interface - around 2.9 uSec vs 4.6. It is conceivable that in much more complex scenes, the async interface would have a bigger % win, since the cost of doing the work would be larger relative to the mostly-fixed cost of launching the request.

Five frames of data for each way:

Async time:2140 ns  Query:954 ns  Total:3094 ns
Async time:2185 ns  Query:235 ns  Total:2420 ns
Async time:2534 ns  Query:326 ns  Total:2860 ns
Async time:1477 ns  Query:203 ns  Total:1680 ns
Async time:4069 ns  Query:344 ns  Total:4413 ns

Average async: 2893 ns

Sync time:3824 ns
Sync time:4046 ns
Sync time:4439 ns
Sync time:5961 ns
Sync time:4458 ns

Average sync: 4546 ns

So, roughly a factor of 1.6 win in favor of the async interface.



Curiously, if instead of doing a world-level trace with one of the UWorld methods, you limit it to a single actor trace with AActor::LineTraceSingle, the total time goes up by about 10X (30-50 microseconds per invocation!). I would imagine it may be bypassing some acceleration structure that the world level trace can use, but I don’t really know the reason.

I think doing a CPU level read of a terrain height map with your own bilinear interpolation would be on the order of tens of times faster than the several microseconds for an async line trace, because it is a more limited task than what the trace methods are doing. However, the texture stored in the ALandscapeComponent is not held in a “simple” linear space, so it would take some doing to figure out what the format is, and/or convert it to something friendlier for the purpose.


I’m interested in using Async line traces. Do you mind pointing me to a class, function call, or some source code on how to correctly do Async line traces?

Thank you.

The AActor::ActorLineTraceSingle does a trace for each primitive component of the Actor. So your mileage here is going to vary wildly with respect to performance depending on the actor. However, this just goes into the Prim Component and does a trace on the BodyInstance itself, so a shortcut would be to just do the component trace with your interested component.