Thursday, July 02, 2009

Going Lock-Free - Shared Resources

X-Plane uses a reference counting scheme for resources like textures and models. Each time some scenery element needs a texture, it asks a central manager to grab the texture. This might result in a new object being created, or it might result in an increased reference count to an existing object.

During the version 9 run it became apparent that a central lock on the "big list of textures" was going to be increasingly problematic - the lock was already showing up in performance profiles under only moderate strain. Clearly a central lock was not going to be an option.

The scheme we use now is based on a central lock that is only needed for resource allocation/destruction - not access. It goes something like this:
  • Resources are always referenced by a pointer, not an index. This means that client code that simply needs to utilize the resource can do so without access to the "central list". Thus resource usage can be lock free.

    (This is the most important case. We only create and destroy a texture once but we might use thousands of textures per frame.)

  • The reference count on an object is atomic, so we don't need to lock the object to add or delete references. From a performance standpoint this is nice but not critical.

  • Resource deletion is explicit. This is the most surprising part: we don't actually release a resource until we explicitly make a "garbage collect" call. This has two effects:

    1. We avoid thrash because we can start re-using a zero-reference object before it is thrown out.
    2. It limits the locking of the big list of objects to one explicit function call.
The result of this is a system that doesn't lock during the main frame loop, under any conditions and doesn't thrash too badly during load.

No comments:

Post a Comment