View Single Post
07-01-20, 04:15 AM   #12
kurapica.igas
A Chromatic Dragonspawn
Join Date: Aug 2011
Posts: 152
Originally Posted by LudiusMaximus View Post
Wow, this sounds amazing. I cannot even begin to understand how this works.
I mean you somehow have to "pass the execution around" (like SDPhantom said) from frame to frame, right? So when WoW is running at 120 FPS you do less lua executions per frame than when it is running at 60 FPS? How does your framework estimate how many lua executions "fit" into one frame, before the FPS would drop??
Task an example:

Lua Code:
  1. Scorpio "ScorpioTest" ""
  2.  
  3. __Async__()
  4. __SlashCmd__ "sct" "start"  -- use `/sct start` to start the process
  5. function bigCycle()
  6.     local time = GetTime()
  7.     local prev = 0
  8.     for i = 1, 10^7 do
  9.         if i%10 == 0 then
  10.             Continue() -- The frame will freeze if miss this
  11.  
  12.             if time ~= GetTime() then
  13.                 -- Means the thread is resumed in the next frame OnUpdate
  14.                 time = GetTime()
  15.  
  16.                 -- Here is the current time and the cycle count of the previous phase
  17.                 -- On my laptop(i7-9750H), it's about 14600(10 level) or 20000(1 level)
  18.                 print(time, i - prev)
  19.                 prev = i
  20.             end
  21.         end
  22.     end
  23. end

Dont' mind the __SlashCmd__, it means use command "/sct start" to call the function bigCycle, the __Async__ means the function will be processed in a coroutine, there are many ways to simple code like this.

The blz provide the debugprofilestop, so we can mesaure the cost of code in one frame(The GetTime() can't do that, since it won't change the result during one frame)

The core part in the example is the Continue API provided by the Scorpio. It'll yield the coroutine, queue it to a high priority task list. So the code is stopped, the task schedule system will check if there is still enough time in one frame, if it's has, the system will check the task list, and resume each task one by one until there is no task or not enough time.

The time limit for one frame is calcluated by the fps, it is less in 120 hz game than the 60hz(but normally the CPU is more powerful in the 120 Hz hardware platform).

The system will also try to calcuate the average cost of the codes(from resume to the yield, since many codes doesn't finish in one frame), so if there is too many tasks, the task system will try to get more time to reduce the amount of the tasks, but with a max time limit, the fps dropping could be unnoticeable, we still can change the max time limit to make sure no fps dropping.

So to dot it, we need a task schedule system to manage the time and resume the tasks, and several async APIs like the Continue, Delay and etc to queue the tasks into the schedule system, so we can manage them no matter where and how the code works.
  Reply With Quote