I wanted to create a system that runs single threaded, but on the different thread. And apparently eventho the script is in actor, it fails to go in parallel, and block the main thread (In client and studio).
Place:
ParallelBs.rbxl (75.0 KB)
Script1
local actor = script.Parent.Actor
task.wait(4)
print("send parallel", os.clock())
task.spawn(function() --task.spawn just in case
actor:SendMessage("Test")
end)
task.wait()
print("start calculation", os.clock())
local result = 0
for i = 1, 10000000 do
result = result + math.random()
end
print("End calculation", os.clock())
Actor/Script
local RunService = game:GetService("RunService")
local actor = script:GetActor()
actor:BindToMessage("Test", function()
task.desynchronize()
print("start parallel", os.clock())
local startTime = os.clock()
local result = 0
for i = 1, 100000000 do
result = result + math.random()
end
local endTime = os.clock()
--debug.profileend()
--task.synchronize()
print(string.format("Parallel work took: %.4f seconds", endTime - startTime))
print("End parallel", os.clock())
task.synchronize()
end)
Result:
send parallel 4953.976478
start parallel 4953.976822999999
Parallel work took: 2.3033 seconds
End parallel 4956.2805585 -- "parallel" blocks the main thread
start calculation 4956.282700899999
End calculation 4956.5102467
1 Like
This is actually expected behavior. When you have scripts under different Actors running desynchronized, those scripts can run in parallel. However, the main thread does not run in parallel with the Actors.
The reason the main thread doesn’t run in parallel is that it can call API’s or modify the DataModel in ways that are not thread-safe and could actually interfere with other scripts running in parallel.
If you modified your sample so that you have multiple Actors then you should see that multiple actor scripts can run in parallel when desynchronized.
1 Like
I see, thank you for explanation. Would be really nice if there was an option to run it in parallel with the main thread
1 Like
Btw, quick question. What happens if you assign too much parallel work for actors? Does it just do the second iteration before releasing the main thread?
64 tasks
[main thread] - [parallel 32 tasks] - [parallel 32 tasks] - [main thread]
or
[main thread] - [parallel 32 tasks] - [main thread] - [parallel 32 tasks]
1 Like
Btw, quick question. What happens if you assign too much parallel work for actors? Does it just do the second iteration before releasing the main thread?
So there is a limit as to how many threads can run in parallel at once (this varies per platform and is also influenced by the particular device itself). So if you are trying to run 64 tasks we likely won’t run all 64 tasks in parallel. However, we do run all of those tasks (assuming they are queued up at roughly the same time) before returning control to the main thread. So it looks closer to this:
[main thread] - [64 tasks] - [main thread]
But as mentioned earlier the 64 tasks won’t all run in parallel, but will try to use all the threads we have made available for parallel execution.
1 Like