Aller au contenu

Photo

How bad are Pseudo HB's?


  • Veuillez vous connecter pour répondre
33 réponses à ce sujet

#1
Baaleos

Baaleos
  • Members
  • 1 329 messages
Ok, I have 600 areas.


Is there any manageable way to Assign a function to fire on each of them, without it eating too much cpu time or lagging.


I already have looped through all my areas on mod load, and have stored an object reference on the Module to each area.

eg

GetAreaByResRef(string sResRef)    // ResRef's are unique, tags are not.

which basically gets

object oModule = GetModule();
return GetLocalObject(oModule,sResRef+"_ar");


I would like to add a pseudo hb to each area, to allow modifications to climate, earthquakes etc and other funky stuff.


Im jus worrying that if I do this, then a Pseudo HB would technically result in 600 Scripts trying to run at the same time?

How would you recommend me doing this?

#2
BelowTheBelt

BelowTheBelt
  • Members
  • 394 messages
My recommendation would be to start the pseudo hb in the OnAreaEnter script and then check for the presence of PCs in the OnAreaExit script. If PCs are found, continue the hb, otherwise exit it.

That way you're only using the hb in the areas that matter- where the PCs are. Even in the largest PW's, that's probably a dozen or so areas at any one point in time- far less than the 600 in your world.

My opinion is that they're in general as bad as a hb script if left unchecked. The benefit of them is that you can turn them on/off only as needed.

Hope that helps.

Hope that helps.

#3
Shadooow

Shadooow
  • Members
  • 4 468 messages

Baaleos wrote...

Im jus worrying that if I do this, then a Pseudo HB would technically result in 600 Scripts trying to run at the same time?

No this is how normal heartbeats works. Pseudo heartbeats runs only at certain circumstances/with higher delay which is what saves resources.

Anyway to your question, pseudo-hbs are more CPU intensive and may even cause memory leak if not done properly. If you got only few variables/instructions then you are perfectly safe with recursive function, if your script is more complex then you should use ExecuteScript command on the same script in conjuction with DelayCommand.

#4
ehye_khandee

ehye_khandee
  • Members
  • 855 messages
Our module is over 1200 areas atm and thanks to clean lean code every step of the way, has no issues with lag/crash/required resets. It _CAN_ be done, just be a mizer with resources as you go, simplify as much as you can.

Be well. Game on.
GM_ODA

#5
FunkySwerve

FunkySwerve
  • Members
  • 1 308 messages
ShaDoOoW's answer is essentially correct. There's NO WAY you want pseudos running in all your areas at once, or even one to cover all areas - they're roughly five times as cpu intensive as heartbeats. If you really must loop all areas every so often, use the mod hearbeat, but by far the more probable scenario is that you only need them running in an area when the player is there. If that's the case, you would fire them off onenter the area, and terminate them when there are no longer pcs in the area.

If you describe in more detail what you're doing, I can offer more specific advice. Also, check to make sure that GetResRef works on areas - it didn't use to, and it still doesn't according to the 1.69 lexicon, but I THINK it was changed in 1.67 or later to work. I can't easily tell because the old forums are down, and the post I remember on the topic isn't showing in the Omnibus.

Funky

Modifié par FunkySwerve, 24 juin 2011 - 12:18 .


#6
henesua

henesua
  • Members
  • 3 863 messages
Why not just write one script for handling the areas, and put it in the onheartbeat of each area. You can control the script to skip processing if no one is in the area, also you can limit its processing further if you index your heartbeats each minute.

Example: you have 10 heartbeats per minute. Iterate a tick count for each mod heartbeat, and store this tick on the mod. when it is greater than 10, subtract 10 from the number. You can then limit your heartbeats according to which HB tick you are on. If it is not the right tick, don't run run script. Basically this could limit your HB script to run only once a minute when a player is present. You can also use this system to stagger your HB processes in different areas, so not all of your areas get prcessed on the same HB tick. Store a local int on the area that identifies which index for the area HB to run.

Modifié par henesua, 24 juin 2011 - 01:18 .


#7
FunkySwerve

FunkySwerve
  • Members
  • 1 308 messages
Because that's an enormous waste of cpu.

Funky

#8
henesua

henesua
  • Members
  • 3 863 messages
Explain. I've got a 1000 area mod and this has almost no impact on it.

#9
_six

_six
  • Members
  • 919 messages
What I do for weather, is instead of looping through all areas, I loop through all PCs and use the area they're in. I also set a variable on the area to mark what its weather should be, and only change it if the current settings don't match the variable on it. That way time is not wasted applying weather effects to empty areas, and I don't do it multiple times if the area has multiple players in it.

Although, this is made much easier cos I only use a single weather setting for the whole world at once, but I think logic based around where players are rather than all areas is the way to go regardless.

#10
FunkySwerve

FunkySwerve
  • Members
  • 1 308 messages

henesua wrote...

Explain. I've got a 1000 area mod and this has almost no impact on it.


It should be fairly obvious. You wind up with a ton of hearbeat scripts firing to no purpose. Even if you end them right away, based on variable or pc presence, you're still wasting a ton of executions. There's just no good reason to do it this way, when there are solutions that are just as simple and result in far fewer scripts firing. The fact that this additional load has yet to push your server's total load into the 'unacceptable' realm, is not really relevant, even anecdotally.

Funky

#11
FunkySwerve

FunkySwerve
  • Members
  • 1 308 messages

_six wrote...

What I do for weather, is instead of looping through all areas, I loop through all PCs and use the area they're in. I also set a variable on the area to mark what its weather should be, and only change it if the current settings don't match the variable on it. That way time is not wasted applying weather effects to empty areas, and I don't do it multiple times if the area has multiple players in it.

Although, this is made much easier cos I only use a single weather setting for the whole world at once, but I think logic based around where players are rather than all areas is the way to go regardless.

Bingo. This is another smart way of accomplishing this. I still prefer firing pseudos from area enter, but a lot of my reasoning is specific to my own module (we have pseudo-handy behavior in a lot of areas, and already have a set of universal area entry and exit scripts).

Funky

#12
Khuzadrepa

Khuzadrepa
  • Members
  • 188 messages
I also agree that from a resource perspective, it's definitely way more efficient to only have it executing where players are.
Sixes, are you doing yours on heartbeat, or doing it from a pseudo?

#13
FunkySwerve

FunkySwerve
  • Members
  • 1 308 messages

Khuzadrepa wrote...

I also agree that from a resource perspective, it's definitely way more efficient to only have it executing where players are.
Sixes, are you doing yours on heartbeat, or doing it from a pseudo?

My assumption was that he was doing that from the module heartbeat. If you're only going to use one for everything modwide, you definitely want it in a heartbeat, because it'll have to run continuously. It'll mean wasted code when no one is an an area that needs special treatment, but not all that much (any exterior area has weather, after all, if we look at sixs' usage). That IS one disadvantage of doing it this way, as opposed to area-based pseudos, but a reletively minor one. By contrast, using a pseudoheartbeat instead of the mod heartbeat would chew up roughly 5 times the cpu, because it would have to run constantly, and because pseudos chew up roughly 5 times the cpu, based on some benchmarking I did a number of years ago (I'd link the old forum post if I could). You only want to use them when the psuedo in question will only be running 20% of uptime or less. Obviously, that's going to vary from script to script - I just use it as a rule of thumb.

Funky

Modifié par FunkySwerve, 24 juin 2011 - 04:01 .


#14
Khuzadrepa

Khuzadrepa
  • Members
  • 188 messages
Gotcha. That's what I was thinking, but he didn't specify from where it was being executed, so I wanted to be sure.
Both approaches seem to be excellent ways to get this done. It's giving me a lot to think about...

#15
henesua

henesua
  • Members
  • 3 863 messages
I believe the heartbeat event runs for each area regardless of whether you apply a script to a particular event. Anyone have evidence to the contrary?

#16
Mudeye

Mudeye
  • Members
  • 126 messages
The heartbeat may run for each area, but if there is no heartbeat script it just checks that there is no script and goes on. If there is a script then the overhead of running that script happens every heartbeat. If you put the script in every area then that overhead adds up.

If you could put some notification information in a variable that indicated that an area(s) needed updating then a single hb script could check that variable and then update the required area(s).

Modifié par Mudeye, 24 juin 2011 - 05:54 .


#17
henesua

henesua
  • Members
  • 3 863 messages
The reason I ask is to defend my suggestion. If you only have two instructions typically running in a HB script (setting a variable and checking a variable) then you are not noticeably adding overhead. Its a minor hit at best even with a 1000+ areas. The engine as far as I understand it, essentially runs the HB event on every area regardless of whether you assign a script.

If NWN has a way of shutting off events that do not have scripts assigned to them, then I agree it is a problem to add scripts to HB events. But I don't believe NWN functions this way. If it does, then I am pleasantly surprised.

#18
FunkySwerve

FunkySwerve
  • Members
  • 1 308 messages

henesua wrote...

I believe the heartbeat event runs for each area regardless of whether you apply a script to a particular event. Anyone have evidence to the contrary?

Do you have any evidence to support this belief? I never saw a Biowarean say as much.

From my discussions with virusman on the subject, every object in the mod is checked in something akin to a giant loop, up until a point when the game hits a given limit (which is why day/light would break, as well, under load). This isn't really like a heartbeat event 'running' when blank. Adding code to execute, especially in every area, is only going to slow things down. I'll point him to this thread and see if he wants to elaborate.

Either way, it's sort of irrelevant, again, because you still wind up executing extra code to no gain. 'It's only a little wasteful' is not an argument for doing something, especially when there are simpler ways to do it more efficiently, and especially when you're doing it a lot. Doing a number of things that, individually, don't add 'noticably' to overhead can add up to some VERY noticable overhead - the death of a thousand cuts, as it were. If you want efficiency, keep your code execution to a minimum.

Also, in your last post, you confused functions with instructions:

If you only have two instructions typically running in a HB script (setting a variable and checking a variable) then you are not noticeably adding overhead.

An instruction refers to machine code, and has no direct correlation to a function - a function can comprise many instructions. Likewise, the TMI limit applies to instructions, not functions.

Funky

#19
henesua

henesua
  • Members
  • 3 863 messages

FunkySwerve wrote...

Either way, it's sort of irrelevant, again, because you still wind up executing extra code to no gain. 'It's only a little wasteful' is not an argument for doing something, especially when there are simpler ways to do it more efficiently, and especially when you're doing it a lot..


Not at all. The argument that it is not very wasteful is relevant because NWN is structured for you to use it in the way I suggested. Which makes it easier for a team to maintain the code, and simpler to implement. Complicated code maintained by an amateur team can get ugly. For a well organized team or a team of one - do whatever you like, but for the typical NWN PW with a team of folks coming and going its just much easier and effective to use the engine in the obvious way.

Now I don't mean to say that what you suggested is problematic. I understand your point about efficiency, and respect it. But my thinking is that if the engine checks heartbeat events every 6 seconds, you are not achieving much by avoiding them because the overhead is already there.

Throwing an extra apple on the apple cart is no big deal.

But if you are creating the apple cart, then I agree its not worth it.

So yes, I would like that clarified if anyone knows. Occam's razor alone suggests to me that the engine functions the way I assume it does. But I would be happy to be proven wrong. I just want to know.

#20
FunkySwerve

FunkySwerve
  • Members
  • 1 308 messages
Eh, fair enough. I do understand and agree with there being a trade-off between simplicity and efficiency. I think I would tend to go with six's method, though, in that case. Unless there were a lot of different types of area effects besides weather, in any case, at which point readability and compartmentalization of code would probably send me towards different heartbeats on the different areas. Then, if I found pseudos too complex or bothersome, I guess I would opt for area heartbeats. Compartmentalization is one of the reasons we use area entry pseudos to begin with.

I did ask virusman to comment, if he wanted, but there's a good chance he's asleep at the moment.

Funky

#21
virusman

virusman
  • Members
  • 282 messages

henesua wrote...

I believe the heartbeat event runs for each area regardless of whether you apply a script to a particular event. Anyone have evidence to the contrary?

When there is no script in OnHeartbeat slot, there is nothing to run.
The overhead of just having an empty area with no scripts is minimal: CNWSArea::AIUpdate only updates weather and calls Heartbeat script every 6 seconds if there is one.
DelayCommand uses complex structures, high resultion timers, saves and restores script situation data - all of this uses more CPU than a simple check in HB timer.

#22
henesua

henesua
  • Members
  • 3 863 messages

virusman wrote...
When there is no script in OnHeartbeat slot, there is nothing to run. The overhead of just having an empty area with no scripts is minimal: CNWSArea::AIUpdate only updates weather and calls Heartbeat script every 6 seconds if there is one.


Thanks for the information. Thats helpful.

What I was referring to as overhead for area HB events is apparently CNWSArea::AIUpdate, since that is what calls Heartbeat scripts. So there IS something to run whether or not you link a script to an area's heartbeat event. However you seem to be suggesting that the process is extremely efficient if there are no heart beat scripts to call.

So is it the case that even a very simple heartbeat script suddenly generates measurable overhead? Even one in which only one or two lines of script are called? I would assume not since the scripts are compiled rather than interpretted, but I don't really know what "compiled" means in an NWN module.

Also does the overhead of CNWSArea::AIUpdate increase as you add areas even if you have no HB event scripts?

#23
Shadooow

Shadooow
  • Members
  • 4 468 messages

henesua wrote...

virusman wrote...
When there is no script in OnHeartbeat slot, there is nothing to run. The overhead of just having an empty area with no scripts is minimal: CNWSArea::AIUpdate only updates weather and calls Heartbeat script every 6 seconds if there is one.


Thanks for the information. Thats helpful.

What I was referring to as overhead for area HB events is apparently CNWSArea::AIUpdate, since that is what calls Heartbeat scripts. So there IS something to run whether or not you link a script to an area's heartbeat event. However you seem to be suggesting that the process is extremely efficient if there are no heart beat scripts to call.

So is it the case that even a very simple heartbeat script suddenly generates measurable overhead? Even one in which only one or two lines of script are called? I would assume not since the scripts are compiled rather than interpretted, but I don't really know what "compiled" means in an NWN module.

Also does the overhead of CNWSArea::AIUpdate increase as you add areas even if you have no HB event scripts?

There is still a question that if you need heartbeat for each area why do you dont use modules's heatbeat and then do stuff on each area.

#24
GhostOfGod

GhostOfGod
  • Members
  • 863 messages
I was planning on putting a blank HB script in all areas as I'm building them just in case I want to put something in later. Now I'm not sure if I should. How much of a resource difference are we talking here?

#25
FunkySwerve

FunkySwerve
  • Members
  • 1 308 messages
Vman's strong preference was for a single modwide heartbeat, when we discussed it at length. That is, unless you have area scripts like drowning, which are somewhat time-critical, in which case he thought pseudos appropriate for those specific applications only. His ideas basically map to mine, though he isn't as fond of pseudos as I am.

There's no profiler that includes this kind of data, so there's no way to tell how much time with certainty. What IS certain is that it's wasting some, and that there's no need to put in placeholder heartbeats. If you need, you can Moneo them in later in a matter of a few minutes. I'll be happy to show you how - it's an incredible utility for any builder to have, making mass edits simple.

Neither vman nor myself could think of any reason to favor using 600 (or whatever your mod's area count is) individual heartbeats over a single mod heartbeat. If you're doing one thing in all areas, it makes no sense at all. Even if you have a fair amount of different applications in different areas, looping pcs and checking their areas was his preferred method (mine is generally pseudos there, in part because of modularity). Both of us think using one heartbeat per area is nuts.

To answer the OPs question, which I just realized I'd overlooked, no, putting pseudos in your areas will not result in you having 1 per area running constantly, if you set them up as area pseudos should be - to start when a player enters the relevant area, and to stop when the area is empty (all that can be done from the onenter script of the area). The only advantages pseudos have over heartbeats are flexibility and precision. You can turn them on and off at will, specify intervals which will be strictly adhered to, and specify start and stop conditions. If you don't take advantage of that flexibility to specify conditions that ensure the pseudo is running for 20% of uptime or less, you're spending more in cpu than a comparable heartbeat. You ensure that, for example, by only having them run when the players are in a given area. Still, though, if you plan to put the same pseudo in every area, then you're going to be wasting a lot of cpu as compared to a module heartbeat (nevermind individual area heartbeats, which are a complete waste), because you're going to have at least 1 pseudo running whenever anyone is around to care about the overhead - more, if your server isn't particularly party-oriented.

Funky

Modifié par FunkySwerve, 25 juin 2011 - 02:56 .