I had quite possibly the worst experience in all my time coding for byond about a week ago. To put a long story short, I spent three whole, full, days trying to discover why my code wasn't working, as the list seemed to disappear for some reason. I got closer and closer, adding logs, recompiling. I even created a backup list, to no avail - it would disappear at the same time. I created a test environment to reproduce it - nothing. I tried a lot of things (including commenting out our error handler to see the raw runtime data), and none of them worked.
It turns out byond ran out of lists. Now, I'm sure there's perfectly reasonable explanations for this. Personally, after three days straight, I'd have accepted Lummox saying the moons weren't aligned right as an explanation.
But, in order to save people in the future from experiencing the pain I suffered, can you please have a warning come in dream daemon when you run out of something? Even the simplest "You have ran out of lists!" would do. Because the cacophany of list related errors such as "bad list" and such did not get that point across at all.
ID:2173365
![]() Nov 15 2016, 7:04 am
|
|||||||
| |||||||
Unless there's a memory overhead for creating lists, I'm certain a) I ran out and b) there was no warning, it just started to delete old lists
The issue was that every movable atom on our codebase for whatever god forsaken reason has three lists created on New() for an atom locking system, even if there's no conceivable way to lock on to it. I was creating a lot of movable atoms - procedurally generating a terrestrial map, but the test environments I created to reproduce it were capable of generating nearly three times more objects so I ruled out memory loss. Furthermore, after removing the list creation on those objects it now works perfectly well. Once I ran out, the only warning I got was "bad list" as far as I can remember. |
DrCelt wrote:
Unless there's a memory overhead for creating lists, I'm certain a) I ran out and b) there was no warning, it just started to delete old lists Yes, there is always a memory overhead for creating lists. Even an empty list will still have to allocate a structure. The issue was that every movable atom on our codebase for whatever god forsaken reason has three lists created on New() for an atom locking system, even if there's no conceivable way to lock on to it. Good gads. |
Yes, there is always a memory overhead for creating lists. Even an empty list will still have to allocate a structure. Even so, would that explain the runtime errors I was getting such as "bad list" and such? The game would run afterwards, dream daemon wouldn't crash, but nothing would work which involved using lists afterwards. Plus, evven if that were the case, I still didn't get an error message saying dream daemon had run out of lists or out of memory or whatever. Good gads. I was understandably horrified when I discovered that. |
I assume you looked into lazy-loading those lists?
On /tg/ we've had a large push recently to lazy load as many lists as possible (great improvements to world loading times and memory usage) our (ported from bay, but updated) buckling, similar to your generic locking system lazy loads it's list, because as above, having even one list on all movable atoms, that the vast majority won't ever even use it just disgusting. More so for you poor guys having 3! |
I'm surprised you guys didn't push that a lot sooner. atom/New() and init procs are absoulte load time killers, and in a game like SS13 that's ruled by reboots, I would've expected nixing those to be first priority.
|
Well I'm with /tg/, and we've got some of (if not the) best server hardware out of the SS13 servers, so memory for us was less of a concern (still a concern however, gains to be made all round)
We've prioritised CPU over Memory in quite a few cases. One such example would be something I call a "typecache", a typecache is just a fancy name for an associative list where the keys are typepaths, and the values are TRUE. this reduces something like: /proc/is_type_in_list(atom/A, list/L) to /proc/is_type_in_typecache(atom/A, list/T) This provides wonderful CPU benefits, since it reduces N+1 proc calls down to 1 proc call (or none, if you were to make it a define) and an assoc lookup, the downside is that these can be quite big, given that they have to store a typepath and all its subtypes to work, usually with multiple "parent" paths in the same typecache. Things like AI targeting benefited from this, as they frequently scan their environment for targets, being able to check if their target is valid or not quickly is beneficial. tl;dr We neglected memory a bit due to our personal server circumstances and favoured CPU, but are now looking into lazy-loading lists wherever possible and such for memory gains. |
In a game like SS13, prioritizing CPU over memory is absolutely the right call.
My point is, though, avoiding the creation of unnecessary lists offers staggering benefits to both. SS13's startup time is poor, and in tg's case it's legendarily poor. Eliminating init procs and New() calls wherever possible offers drastic benefits to that problem, while also reducing memory at the same time. |
Far more likely is that you ran out of memory, and although DD has various warnings for that, it's possible to miss cases here and there. (Also pretty much every program in history has behaved erratically under those circumstances, for the same reason.) That's especially likely in SS13, especially in certain branches like tg that are known for being mondo ginormous.