I believe using events (BindableEvents) should work? I haven’t tested it myself yet, but it sounds like it would after you re-synchronize the VM
Is it possible for pathfinding to be made thread-safe? Pathfinding is one of the most expensive Roblox API and would greatly benefit from being safe, unlocking so many new game ideas that are currently impossible (e.g. hundreds of NPCs accurately pathfinding to a single player).
It would be a massive lost opportunity to keep it unsafe.
Signals do work; just treat the value sent as though it was sent through a remote and that it is a copy of the original (e.g. the table a thread receives has a different reference than the one sent).
Just to make sure since this wasn’t specified in the release notes, since RBXScriptSignal/Once
is going to be added, are you guys planning on adding RBXScriptSignal/OnceParallel
?
Honestly, there is no ‘right’ way to do this. From my experimentation thus far, you can use AttributeChangedSignals to store information on individual actor instances and listen for them in the ‘main’ (serial) thread and the actor scripts (parallel). You can fire these signals from the Actor VM and have the main thread pick them up and access any memory that has been defined in the main thread. You can then update the attributes of your Actors defined in the main thread and these will replicate back into the VM space’s of the Actors.
However, be warned - this be the land of race conditions and data hazards once you open up the possibility of multiple threads accessing the same ‘shared’ memory space at the same time. I’m not sure if this is intentional or not since Actors are meant to be in their own memory spaces. But, you can actually use Instance:SetAttribute() from within a ConnectParallel() call in order to trigger these events from within your VM and have them communicate back with the main thread without having to sync at all. I was totally wrong about this, resynchronizing is required!!!
I hope they keep this in since I was just about to put in my own semaphores and mutexs which would allow for some really sick IPC.
Example of multiple threads accessing same memory space
As you can see, you’re not guaranteed any coherency when goofing around with parallelism at all, guess this is why a lot of functions are not thread safe at all .
That’s clever, and might be of use if Im doing something complex that results in a small value being determined. There’s no way if you’re populating a giant table right? I tried firing a bindableevent with the table and that ended up taking longer to complete than generating the data itself
One of the benefits of parallelism is that you can actually do two things at once! With my current method, one Actor must wait for another actor to finish before it is allowed to look at the table in the main thread. However, there’s nothing stopping me from just putting some semaphores and mutexes in place which allow two processes to access the same table at once in a “safe” way.
So, create the table and process it at the same time. Kind of hard to pull off in a way that doesn’t cause really weird problems. But, it’d be the fast way to do what you’re suggesting (at least from what I’m understanding).
I’d steer clear of bindable events. Each Actor will get it’s own personal copy of the BE you’re attempting to fire so it won’t replicate back to the main thread, nor can you do cross-actor communication with them (could be totally wrong about this).
Another funny thing (as demonstrated in my prior post); Is that Actors (by design) communicate without any determinism whatsoever unless you specifically implement it as such yourself. This is called unbounded nondeterminism because an Actor could given a lot of things to process by other Actors and eventually those things will be processed, regardless of arrival time. It really depends on how your Actors are set up honestly.
Your best bet is to communicate as often as possible. Data taking too long to send when you send it in one huge chunk? Just drip feed it to the Actor that needs it in smaller chunks, they’ll all arrive eventually, even if other processes are accessing that same Actor. Data taking too long to generate? I’m sure that Actor that needs it would be happy to process smaller chunks of it while the Actor that’s generating it keeps generating it.
Hopefully I’ll have something to demonstrate what I mean soon. But, I’m sure others could chime in and explain this stuff way better than my (likely) misinformed understanding of how Actors should/could/do work.
How does this affect code that is running on the server? I have a game that runs some extremely extensive processes (to the point that I have to implement waiting to prevent CPU locking) for full map saving and loading of a large map.
In my specific case:
- Would implementing parallel Lua this mean that the CPU no longer locks for my operations, as a theoretically more efficient backend could handle prioritizing the main thread over the saving system’s thread(s)?
- Would doing so actually improve the performance in some meaningful way? Currently, the runtime of a full map save is around ~88-92 seconds with a fair amount of intentionally added delay in order to prevent the player’s experience from being heavily affected.
I am glad to see this come out and personally know some people who have been waiting for this to optimize their CPU-intensive tasks. Very cool!
-
I wouldn’t recommend “parallelizing” your backend. Actors lack the concept of a global state so giving them the duty of processing “backend” things wouldn’t work.
-
If saving your map is an operation that can be parallelized (split into asynchronous, purely local, and independent Actors) then yes! Map loading is likely to benefit from this because you can give Individual Actors the job of loading parts of the map in chunks/regions.
I’m still entirely confused on how to use this. Does the actor need to clone and go into things that need to run it? Say I have several hundred parts that need to do some ray math, do I have to clone an actor into every single one or parent them under the actor? I tried looking for tutorials and examples but few pop up.
Do microprofilers currently support parallel Luau? it seems like my code isn’t actually being ran in parallel despite them being under Actors:
I’m having the same problem, I can’t seem to get any code to actually run on separate threads even when the scripts are in separate actors and I’ve called task.desynchronize().
Why did you put up a picture of Massless?
Pretty sure it was to show that the new documentation shows whether or not properties are read or write safe in parallel code.
Cool stuff but I am wondering:
Can you run multiple instances of a modulescript (constructor call with modul.new()) that have been required by one script in true parallel mode?
Since the script itself is the child of an actor, shouldnt all the instances created by this script run under the same actor and thus run in one thread on one core?
Then the code would not parallelized - only run in another phase.
You are absolutely right XD I am not sure what I was thinking of lol
Sorry!
If all of the objects are constructed by the same script, then they will be ran on the same thread.
Light mode when? It hurts to read in dark mode.
Very exciting, but I’m still waiting to be able to edit at least the position property in parallel. Hopefully that’ll be sooner rather than later.