How do you know how many Actors you should use? (Parralel luau)

Hello fellow developers,

for the past few days, i was thinking to make a so called entity system (module). I would very much like it for that module, to be able to run parralel luau (link here). But i was stuck, before even starting on the working on the module, to know many many actors i should use.

On the parralel luau (the link i sended) tutorial, there they didn’t really explained on how many actors is the most optimal to use.

So my question is:

How can i know (in general and in my case) on how many actors i need to use.
(These actors are server-sided (in my case), but i would also want to know, on how i could know, on how many actors i should use in any case. Some examples would be really nice.)

in my case i have thought of the following:

  • 1 actor per entity.
  • having 16 (or 32) actors, and splitting all the work between them.
  • Having 4 (or some other number) actors per player in the game, and splitting all the work between them. (so more players means more actors, which would probably result in also more entities spawning.) (i though that this was the best option.)

Since i didn’t found any good recource that explained it, i though that i would make a devforum post myself. If i made any mistake, please inform me. If you have any helpfull links, feel free to share them with me as well.

Thank you for your time.

1 Like

Roblox wants you to use actors freely, which is partly the reason why the Actor class itself inherits the Model class. The idea was to decentralize the entire game load and have the engine figure it out all on its own.

BUT, for mathematical-related workloads, you will encounter bandwidth bottlenecks when trying to exchange data across actors. This is when you should minimize and centralize them. But this also means it’s not so free to randomly assign actors to spare cores; if there’s any actor left over from the division, their computation will slow everyone down because their execution is deferred. In this case, you can just ask the player directly for their CPU core count, or use some kind of algorithm to figure that out automatically (which I don’t know of a method yet).

Than you for responding,

What exacly do you mean with “have the engine figure out all on its own.”

And as i said, i am using serversided actors, if you misread it. So i am not sure what you mean with this.

The engine automatically distribute actors across cores

iirc the server always run on 16 cores, not sure though.

1 Like

Well, this the image you sended:


it said that you should even use 64 actors, even for 4-core systems.
Thats 16x more actors then cores. Then why is it even worth it? (I don’t understand the explanation.)

Can you explain this better?

Thank you.

If you don’t have tons of entities, using 1 actor per entity is encouraged by the documentation.

If you have tons of entities, if it’s convenient, you could use somewhere between 16 and 64 actors (documentation seems to suggest 32 or 64), and split up all the work between them.

Each actor is assigned to 1 of ~16 VMs (number subject to change at any time since Roblox hasn’t documented it - for all I know it might depend on the device, too!). Each VM is usually assigned to a core – this assignment changes regularly as Roblox tries to balance the load (though in my testing I’ve seen it assign all the VMs I was using to a single core for a brief time - like a frame or two). Thus, there’s no benefit to using 4 actors/player – just use the 16 (or 32+ as documentation suggests) actors and let Roblox distribute the work.

Note: Once an actor is created, Roblox assigns it to a VM. Once this assignment is made, it cannot be unmade, regardless of how much processing that actor ends up doing. The best Roblox can do is try to spread out the VMs onto different cores to balance the load. This is why having more actors is encouraged: it makes it less likely that you’ll have just 1 actor doing a ton of work.

I think the more important consideration is how you’ll be sharing information, and what information needs to be shared between entities. If you’re using Roblox’s SharedTable, then it probably won’t make much difference whether you’re using 64 actors or 1000.
If you have multiple ideas on how to proceed, you can always try one and then stress test your project (for instance, see how many entities you can simulate before you get to a specific fps), and if you aren’t satisfied with the performance, then try the alternate approach and see if it’s any better.

3 Likes

What I’ve actually been really curious about is if using many actors creates any additional overhead or memory usage.
For one of my projects I will likely have all NPCs and even projectile simulations all multi-threaded to make the system scalable even over 64 cores.

I myself have a 16 core processor that can run 32 threads so I definitely want the entire system to be as scalable as possible.

I use module scripts but I’m uncertain if it helps reducing the memory if multiple actors can borrow code from the same module instead of having copy-pasted scripts.
It’s all stuff I haven’t had a lot of time for to look into yet.

Where did you get all of this information from about parallel Luau? I’m seeking to learn more low level details about it.

Where did you get all of this information from about parallel Luau?

Documentation + experimentation.

What I’ve actually been really curious about is if using many actors creates any additional overhead or memory usage.

I assume there’d have to be at least a little of memory overhead (but might be no more than just the cost of having an Instance) - but you could always experiment to see how the performance is, having say 64000 actors performing 100 calculations vs 64 actors performing 100k calculations or something. You could compare both memory and performance and see if there are any differences. (I’d be curious to hear the results if you give it a go!) I expect memory would have to be larger in the 64k actors case, but not sure if it’d be larger than 64 actors + 64k instances (well, 64k*2 since you need a script inside each actor). As for performance overhead, I haven’t tested but is there any cost other than Roblox load-balancing the cores? (Not counting the cost of your code having to coordinate on multiple threads through SharedTables or whichever strategy you use.)

I use module scripts but I’m uncertain if it helps reducing the memory if multiple actors can borrow code from the same module instead of having copy-pasted scripts.

Out of curiosity I tested this and it looks like copy/pasting scripts is actually just as efficient as :Clone()ing at runtime or using ModuleScripts (unless even 1 character is different between the copy/pasted scripts, in which case much more memory will be used). In any case, any memory required by the scripts is increased if you use Actors due to the different VMs.

You can see if Roblox uses more than 16 VMs on your system by creating 32+ actors and seeing which ones can’t share information by requiring the same ModuleScript. For instance, if the ModuleScript is literally just return {}, the script in each Actor could simply be:

local data = require(workspace.ModuleScript)
if not data[1] then
	data[1] = true
	print("On own VM")
end

One last thing I just tested: using SharedTable is ~10-20x slower than just using a table (tested in the Command Bar, so in practice it might be slightly worse if multiple threads end up trying to modify it simultaneously) – and SharedTable.update seems to be ~90x slower than just updating a regular table directly, so with whatever strategy you use, ideally you minimize the number of times you access/modify them.

1 Like

Just to be sure, originally, I wanted the module to have a table that stores all of the entities, so each actor would require that module, and get which entities it should manage (and the information about the entity). Would this be fine or not?

I think the general questions for Actors could be:

  • What computation are you trying to split up?
  • Can you split it up in such a way that requires no/minimal communication between the Actors once the task has been given? (If not, you might be better off not using Actors/SharedTables at all.)

In your case, I think it depends on how much you’ll be accessing & updating values on entities versus spending computation time processing that data. The more that the entities need to access values on each other, the less likely that you’ll see much/any performance benefit.

If you’re uncertain, you should probably just write your system so that you can easily switch between using Actors & SharedTables vs not, to see which gives better performance.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.