Remove the CPU cost of having memory and scale available memory akin to CPU



  • Is there actually a limit of how many flags you can set? I haven't seen any in the documentation.

    Otherwise I suppose at some point someone will exploit it (or have a bug in the code) and put down millions of flags, and the devs will have to act. This kinda prevent me from using flags, as I expect them to be nerfed at some point.


  • Culture

    I think you have to see over how you use memory. My memory cpu usage is non-existent and I don't use flags to compensate it.



  • I'm in the same boat as Stybbe; I'm running 8 rooms and the test code in the link Dissi posted (updated to use Game.cpu.getUsed() instead of Game.getUsedCPU() ) shows me burning less than an average of 0.7 CPU per tick, with a highest value of 1.9.  Visually watching the data, most ticks are around 0.5.  At < 1% of my total available CPU, that's really not a problem yet.  I would not be surprised if it becomes a problem later... but as Dissi pointed out, that's an end-game optimization concern, and it provides a new challenge there.

    Using flags as binary flags is an interesting solution I'd been considering from an ease-of-modification standpoint and I should move to that so I don't have to make a full commit just to toggle on/off debug output.  I haven't actually implemented any of that yet though; I'm just running off direct memory accesses.



  • Actual usage depends on how you use the memory. I had the robust build from the very start that is flexible and configurable per room with memory in fine grain details, with order of things, turret targetting priorties, how to handle repairs etc, all of those are defined in memory. And that comes from the simple fact that this is what memory, at least from new players perspective, seems to be for - data you want to be persistent and available as you go along. Moving them from all rooms to binary flags and/or single units of memory shared across rooms with option to override + couple other "optimisations" to make it work better with the basic serialiser didn't shave off 1.9 cpu, it shaved 10 of it. 

    And really, for what gain is that there? We already have people using very little memory (I will be very surprised if there is more than 2 hands worth of people how utilise half of it), a resource that in normal programming is extremely valuable and used in exactly as container for arbitrary data and structures that we want to work on to save CPU, not potentially increase it. I simply fail to see any reason for it to exist as it is now, as it only adds some arbitrary complexity and raises the entry ladder by a pitfall. Worth adding that unless you profile especially for it you won't even know that it's ruining your perofmrnace, because who would expect memory to cost you CPU just for having stuff in it?

    Seems like a lot of bad to me for really little (no?) gain. We could still force people to optimise their memory by drasticly reducing it's availability, without the hidden CPU tax and with increased transparency.


  • Culture

    > who would expect memory to cost you CPU just for having stuff in it?

    Well, if you searched for it on the site, you would know, because one of the very first articles turned up tells you about it.

    It's intended behavior. Your memory costs more or less to deserialize based on how you write your code, and whether you like it or not, that cost has to be paid by someone. Either you pay for it, or the server gives it to you for free.

    It clearly used to be free - but that means that the server now takes on additional load and ticks take longer to execute.

     

    By the way, I use memory extensively and it never takes me more than 5 cpu to deserialize. Yeah, you're going to have to learn to optimize your code in ways you didn't think were important to write an AI. That doesn't mean that you shouldn't have to do it just because it doesn't meet your expectations.

    It's very unlikely that a beginner will ever run into this problem, and when they do, they've probably written quite a bit of code. Expecting to have to optimize it later is just par for the course.



  • Given that explanation of it only exists in that changelog and on bottom of single documentation page + the fact that many people do not know about it tends to beg to differ. Granted that it's easy to find it once you know about it, but isn't everything?

     

    But that is beside the point discussed, could you maybe elaborate and explain  what would be the downside of proposed solution? You will still need to optimise your memory, hell, more than you do now most likely, but the limitation and costs of it will be visible and transparent even at a glance, not hidden and require dilligent profiling. 

    It's also worth noting that the code you are shown in tutorial, which I imagine many players use as base to build upon, is actually extrmeely prone to cpu-heavy memory generation. And all that for gameplay benefits that, at least for me, remain a mystery.


  • Culture

    If it's just a documentation issue, sure. The documentation should be better organized.

    It's not about gameplay benefits, at least not directly.

    The way you structure your memory has an impact on its deserialization cost. That is reality. It is physics. You can't just handwave it away and say "well, I should get that for free!" You can store 1MB of data that doesn't cost very much to deserialize, or you can store 20KB that costs a huge amount to deserialize. If you don't pay that cost, then who? The servers have to deserialize your memory. It's either charged to you or it isn't, and if it isn't, well, then the players won't be aware of that cost, and they'll structure their memory in a suboptimal way, and we'll get 20 second ticks because no one understands what the true costs are.

    The tutorial has you using at most... three? memory values. All I can recall is the state variable for the creep that controls whether it's dropping off. That's hardly leading you down a garden path, and a single value per creep is not going to work.

    Look, I'd love to get 200KB of memory and a free deserialize step. But I know that's not going to happen because deserialization has a CPU cost and someone has to pay it. And it should be me that pays it, since I'm the one that decides what goes into it. Putting the responsibility on the players means that we all benefit from faster tick times.


  • Culture

    "a single value per creep is not going to work" should be "a single value per creep is not going to be any sort of problem".



  • So while you agree that it doesn't benefit the game in any way, or at least can't come up with any reason how it does, you say that it should stay as it is anyway becuase in your guess otherwise the game will, I don't know what, financially collapse? Tick will become 18 seconds long? Either of this is a business issue, on which neither of us has competency or necessary knowledge to discuss with any merit (unless you are one of the devs and have access to business numbers), so let's stay at discussing what we can be certain about - gameplay.

    But as much as I would like to, there is just nothing else for me to add in that regardas you didn't raise any gameplay points to tackle. Best I can do is reiterate that this is creating an uneccessary learning curve without apparent benefit which is not good for new players in any way shape or form.


  • Culture

    The gameplay benefit is the same as the reason for limiting CPU. Your code has costs. You should be charged for those costs. You should optimize your code to reduce those costs. There's no reason to optimize for costs you can't see.



  • To reiterate what you said is: "we need to put the artificail cpu cost in that doesn't make sense from gameplay perspective but we do so for [business reasons]" and outside of devs we are not in position to make or suggest that call.

    And if were to read the suggestion entirely, and the replies, no one is suggesting to remove limits on memory, quite the opposite - limit it more and make it scale with GCL.


  • Culture

    It isn't an "artificial cost". It exists. It is a real cost. You can affect the cost through the way you use memory. Therefore you should pay the cost.



  • Can somebody please provide a link with a good and full explanation how object design affects JSON (de-)serialization times/load and how that can be minimized?


  • Culture

    I don't have a link to a doc handy or anything. The short of it is that more objects cost more to deserialize.

    So as a trivial example, storing a path as 50 RoomPosition objects, i.e. 200 discrete values (the object itself, as well as x, y, roomName) is less efficient than coming up with a way to encode that path as a single string.

    Note that in that case you will still pay a cost when deserializing that path to its final form. The cost you're saving is the per-tick deserialize cost; you now have a new problem, of course, in writing an efficient mechanism for transforming that value back into something you can use. But you probably don't need every path you've cached, every tick, so even an inefficient algorithm for using the value is going to see a benefit over storing the raw RoomPositions in a large cache.

    (I don't even bother with this yet, I just store the raw RoomPositions. But I'm aware that that won't scale.)

    As for serialization, good news! That actually is free. It occurs after you return from your loop.



  • So the most performant approach would be to save it ALL as one large string and use something like an adress dictionary and areas having a fixed width or the like, just like hard drives are doing it .. !?
    Sounds fun. Hardest question is how to manage that adress dictionary. In a performant and convenient way.


  • Culture

    Yes! And if you go that far, you could use RawMemory and not even pretend to be using JSON. 🙂