Re:An Architecture for Millions of Things
by wyager on Wednesday July 13, 2016 @09:15PM
(#12091058)
Interesting project. A few pedantic points:
> let's have a look at the very few CPU center-of-attention prediction rules:
Modern high-end CPUs have incredibly powerful branch and cache prediction machines that use much more complicated rules than the 3 listed here.
Additionally, the actor model is horrible for cache consistency. Actors only run for short bursts, so both the instruction and data caches are constantly getting blown out by context switches (even lightweight context switches that don't involve the OS). By their very nature, actors are focused on different things. The "loop over lots of objects" paradigm would almost certainly deliver higher cache performance, at the very least because you're running the same code over and over again.
Edit: that's not to say that the actor model gives worse performance in general - just for certain workloads.
Re:An Architecture for Millions of Things
by jdmichal on Thursday July 14, 2016 @02:02AM
(#12091942)
The author clarified on Reddit [0] that the lists are separated per type, so a list will only contain data for a single actor. So the actors are likely looping over lists and processing each entry, which should look to the CPU like any other array-processing code and optimize pretty well. It's a bit deceptive, since actors would typically be isolated. Instead, it seems like the "big idea" here is simply separate different data types into different lists and process them with different threads, using message queues as the concurrency mechanism.
Re:An Architecture for Millions of Things
by anselm_eickhoff on Thursday July 14, 2016 @08:19AM
(#12093105)
Exactly, and messages are divided into buckets which contain only one kind of (type of message, type of receiver)-combination. If you then iterate over that, you are going to execute very similar code repetitively.
I guess my epiphany was that exactly because actors are isolated, I could manage them like this and do some very primitive fast array iteration, while still using a nice high-level pattern to implement the actual game logic.
Re:An Architecture for Millions of Things
by Animats on Thursday July 14, 2016 @12:38AM
(#12091655)
OK, so someone is writing a city simulator/game, with millions of actors. Fine. They're not very far along yet; there don't seem to be any demo images. Yet they're obsessing on CPU cache management. This seems to be premature optimization.
Their big problem is making a procedural city generator that produces a convincing city at street level. There are lots of floorplan generators and things which produce vaguely reasonable buildings, but nothing good enough to make a video game grade driveable or walkable city down at street level. Unless they crack that problem, their game is going to suck.
Re:An Architecture for Millions of Things
by yetihehe on Thursday July 14, 2016 @02:33AM
(#12092028)
If you need to do something which was never done because of efficiency problems, you need to think about how to do it before you start. It's called planning, not premature optimization. Just optimizing existing approaches won't do anything good here as author said in beginning.
Re:An Architecture for Millions of Things
by ggambetta on Thursday July 14, 2016 @07:00AM
(#12092811)
It is a bit premature in a way; paraphrasing here, but "a million is not cool. You know what's cool? A billion" No matter how much you optimise CPU caches and memory allocators, at some point your application won't fit in a single machine, and you'll have to go distributed. Datacenters, not mainframes :)
Re:An Architecture for Millions of Things
by majewsky on Thursday July 14, 2016 @07:43AM
(#12092967)
Assuming that he is talking about a city sim as a game, I can understand that he doesn't want to use the GPU for the simulation, since it will be occupied with the (even more expensive) rendering of the city.
Re:An Architecture for Millions of Things
by josephg on Thursday July 14, 2016 @01:44AM
(#12091883)
The author describes performance problems with existing heap (malloc) implementations, then describes their own memory allocation algorithm system like this:
- things of roughly similar total chunk sizes (constant + dynamic part) are stored in one "bucket", laid out contiguously in fixed-size slots, with a little leeway for growth inside
- there are buckets for each existing size of a thing
- if a thing outgrows the slot size of its bucket, it simply migrates to the bucket with the next bigger slot size
Isn't this exactly how many (most?) modern malloc implementations work? ... A series of buckets for different sizes of objects, combined with bitfields or free lists to keep track of which slots in each bucket are free?
Re:An Architecture for Millions of Things
by anselm_eickhoff on Thursday July 14, 2016 @08:15AM
(#12093085)
(author) I made the mistake of writing a blog post targeted towards non-programmers, leaving away a lot of essential detail. For example that buckets only contain one kind of actor or message and because of indirect references can be deallocated by a simple swap-with-last, so no free-lists are needed
Re:An Architecture for Millions of Things
by ggambetta on Thursday July 14, 2016 @07:10AM
(#12092848)
We offer a C++ SDK that would allow anyone to integrate anything as a worker, as long as it speaks a simple protocol - essentially, receiving updates from the platform, and sending updates to the platform. It would be completely viable to use a GPU to do some intensive computations and send the results back as updates.
> let's have a look at the very few CPU center-of-attention prediction rules:
Modern high-end CPUs have incredibly powerful branch and cache prediction machines that use much more complicated rules than the 3 listed here.
Additionally, the actor model is horrible for cache consistency. Actors only run for short bursts, so both the instruction and data caches are constantly getting blown out by context switches (even lightweight context switches that don't involve the OS). By their very nature, actors are focused on different things. The "loop over lots of objects" paradigm would almost certainly deliver higher cache performance, at the very least because you're running the same code over and over again.
Edit: that's not to say that the actor model gives worse performance in general - just for certain workloads.
[0] https://www.reddit.com/r/programming/comments/4sp25q/xpost_r...
I guess my epiphany was that exactly because actors are isolated, I could manage them like this and do some very primitive fast array iteration, while still using a nice high-level pattern to implement the actual game logic.
Their big problem is making a procedural city generator that produces a convincing city at street level. There are lots of floorplan generators and things which produce vaguely reasonable buildings, but nothing good enough to make a video game grade driveable or walkable city down at street level. Unless they crack that problem, their game is going to suck.
Highly doubt that.
Oh, and when I see a phrase "millions of things interacting" and don't see a word "GPU" anywhere I feel strange. Just saying.
Dev blog: http://www.introversion.co.uk/subversion/
Post 12 is especially relevant to the 'convincing city' discussion: http://forums.introversion.co.uk/viewtopic.php?t=41634
Edit to add: Amazing to think that this was happening 8 years ago. I wonder what it would turn out like if they took another crack at it today.
Procedural building generation is indeed one of the other huge topics of the project and believable, unique street-level looks a main goal.
- things of roughly similar total chunk sizes (constant + dynamic part) are stored in one "bucket", laid out contiguously in fixed-size slots, with a little leeway for growth inside
- there are buckets for each existing size of a thing
- if a thing outgrows the slot size of its bucket, it simply migrates to the bucket with the next bigger slot size
Isn't this exactly how many (most?) modern malloc implementations work? ... A series of buckets for different sizes of objects, combined with bitfields or free lists to keep track of which slots in each bucket are free?
Disclaimer: I work at Improbable
Can't find if you're using GPGPU for (maybe some simple, but not complex?) workers or not?
Here's an example of a custom worker: https://improbable.io/2016/04/21/create-custom-flocking-work...