Notes on API concurrency
John-Nagle opened this issue · 3 comments
@cwfitzgerald wrote previously:
I think it would be a more accurate and more honest api design to do away with the implicit double-buffered queue and be up front about the requirement that a chunk of the processing happen on one thread while still allowing loading and other memcpy-type things to happen on other threads:
I've been thinking about this, and here's a possible way to do that.
There are two kinds of requests to Rend3:
- The ones whose names begin with "Add" (AddMesh, AddMaterial, AddObject, AddTexture) do not affect existing objects in the scene. They can potentially be done from any thread and need not be frame-synchronized.
- The ones which begin with Change or Set (ChangeMaterial, SetTransform, SetSkeletonJointDeltas, etc.) need to be frame-synchronized for animation to work. So they should be queued.
That takes care of most of the cases I see.
Queuing is related to Issue 392. The way to do animation without making the main thread wait looks like this:
Render thread
loop
swap instruction chain (new feature requested in Issue 392)
send go to animation thread(s) computing positions for next frame.
start render thread
end loop
Animation thread
loop
Wait for go signal from main thread
compute positions for objects for next frame
call Change / Set functions to queue movement actions for next frame
end loop
Loader thread
Load new content using Add functions as it comes in from files and networks.
The idea is that the animation thread should finish its work within one frame time, but if it doesn't, it just means
movement updates are slow. Might have multiple animation threads, for high and low priority movement.
It would be helpful to have ChangeObject in the API. This would be a queued operation, used when something is changing meshes between frames. (This happens in Second Life during editing). It would be equivalent to deleting and re-adding the object, but synchronized.
I'm doing animation now using the threads discussed above, which gets all the movement computation out of the main thread. Using the new explicit instruction list swap. Working fine.
Still need fully concurrent AddMesh, AddMaterial, AddObject, AddTexture, to get performance up. The main thread is overloaded while content is loading, which is most of the time.
All the Add* functions are parallel on the rend3 side at this point, further performance is blocked on gfx-rs/wgpu#2710
I think we can now close this!