Resync
Parallel Luau library with a simple synchronous thread pool API for dispatching tasks.
Links
About
Resync introduces a ThreadPool class that can be used to perform tasks in parallel. The ThreadPool class provides an easy-to-use synchronous API for queuing and dispatching tasks, making it simple to execute parallel tasks from a serial context.
Why use this over all the other parallel computing libraries?
Like all other resources I’ve published over the years, the point of Resync is not to compete with existing or future solutions. Make your choice based on whichever library provides an API that fits your specific use cases or preferences.
Benchmarks
Benchmark figures
Average time per sample taken to calculate a varying number of octaves of 4-dimensional fractal noise. Parallel benchmarks were done by dispatching one task per sample. Unsafe thread pools have Resync’s optional thread scheduling safety disabled.
Similar benchmark repeated with a much higher number of octaves per sample.
Installation
Two different installation methods are supported:
Rojo with Wally
- Install Rojo and Wally.
- Add Resync as a dependency in your
wally.toml
file.[dependencies] resync = "tenx29/resync@1.0.1"
- Run
wally install
.
Manually in Roblox Studio
- Get the latest version of Resync from the GitHub Releases page or the Roblox Creator Store.
- Insert the model to your project and place it to the location of your choice.
ReplicatedStorage
is recommended as it allows both client and server code to access it. - Require the Resync ThreadPool class in your code.
local ReplicatedStorage = game:GetService("ReplicatedStorage") local ThreadPool = require(game.ReplicatedStorage.Resync.ThreadPool)
Code Example
Below is a very simple code example showcasing how to use Resync to run tasks in parallel. More in-depth instructions and a comprehensive listing of available methods can be found in the documentation.
MyTaskModule, a ModuleScript used as the worker function
return function(actor: Actor, threadId: number, message: string)
task.desynchronize()
task.wait(2) -- Simulate work
print(message)
-- Optional, Resync takes care of synchronization after the task is done
task.synchronize()
end
Script that creates the thread pool and dispatches the tasks. For this example, the script is located in the same place as MyTaskModule.
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ThreadPool = require(ReplicatedStorage.Resync.ThreadPool)
local MyTaskModule = script.Parent.MyTaskModule -- Note that require() isn't called
-- Create a thread pool with 64 threads
local myThreadPool = ThreadPool.new(MyTaskModule, 64)
-- Add 64 tasks to the thread pool
for i = 1, 64 do
-- The Add method can accept any number of arguments of any type,
-- which are passed to the worker function after the thread's Actor and ID
myThreadPool:Add(`Task {i} done!`)
end
-- Execute all tasks and wait for them to finish.
myThreadPool:DispatchAll()
-- If we wanted to combine the results of all threads, we could for example use
-- a buffer and pass the buffer offset as an argument to the worker function.
-- Implementation details like this aren't included in Resync as it's specific to
-- the user's use cases. This is left up to the user to implement.
License
Resync is fully open-source and free to use with an MIT license.