riperiperi / FreeSO

Re-implementation of The Sims Online.
http://freeso.org
Mozilla Public License 2.0
817 stars 95 forks source link

[VM] Smarter Idle with Scheduler #33

Closed riperiperi closed 7 years ago

riperiperi commented 7 years ago

Most objects in a lot are completely inanimate, eg. windows, doors, chairs, counters, but still perform a full VM tick every frame. This tick usually consists of initializing the execution context, checking to see if it is valid, checking interaction status, finding the top stack frame, getting the current instruction & its handler, running the Sleep primitive to poll for interrupts and decrement the parameter (one of the 20000 ticks the object wants to sleep for), handling its return value and then doing a few other checks and background operations that really could be skipped for most objects.

I would say over 90% of objects in most lots have a main method that is literally just "idle 20000 ticks", as the objects do not need to animate or do any kind of internal polling. The tick function also performs some operations to do with currently playing sounds and headlines, which are in an even smaller minority, yet are currently run constantly on every object. It is only important to run entity and thread ticks every frame on avatars.

The solution would be to implement a "schedule", where the VM would only run ticks on the objects that have been "scheduled" to continue executing on that frame, instead of all of them. The thread would be extended to include an internal timer to indicate how long it has been dormant for, so time sensitive variables can be updated accordingly. For example, an object entering idle for "20000 ticks" would schedule itself to run again on tick (current + 20000). If it is interrupted out of idle by another object, this registration should be moved to (newCurrent + 1) to execute as soon as possible. Its "Tick()" function would never even be touched for the frames where it is not scheduled, saving execution time.

When idling in freeso.ml, VMEntity ticks take ~79% of the internal tick's execution time. If we could strip out this theoretical 90%, that's an easy 3.5x speedup for idle lots. This would make it a lot easier to host lots on the MMO server, and a little easier to run on slower devices. The bottleneck would quickly become the renderer. (yes, even more than it is now)

Things which need to be considered:

riperiperi commented 7 years ago

Completed in server-rebuild. Might want to separate headline and sound updates from the thread scheduling, so they don't have to force thread updates every frame. Scheduling information does not need to be synced. Forum link shows performance is definitely improved.

http://forum.freeso.org/threads/final-checklist-gif-heavy.2314/page-2#post-22925

https://github.com/RHY3756547/FreeSO/commit/c25f7d009e92f5470476325aed63f91f71667bd7

Might be a small issue with some threads somehow descheduling forever (duck did this, some resyncs in restaurant), but if the tick function runs through it should be able to emergency reschedule.