PDA

View Full Version : Does timers help to handle large checks?


MindeLT
01-01-2012, 17:52
Hi,

does creating a timer to handle huge checks, for example, outside EventPlayerSpawn callback helps you to improve your server performance?

For example, instead of using huge checks in same events:

public EventPlayerSpawn(Handle:event,const String:name[],bool:dontBroadcast)
{
if(check)
if(check
if(check)
lot of code here
more code here
}

i would use

public EventPlayerSpawn(Handle:event,const String:name[],bool:dontBroadcast)
{
CreateTimer(0.0, Timer_To_Handle_Checks);
}

Impact123
01-01-2012, 21:49
This is an interesting question, but i don't think so.
If we assume that the event normally happens before the message, then this should not be a problem, also i don't think this is one of the "heavy" events.

Yours sincerely
Impact

MindeLT
01-02-2012, 05:08
But if server is 40+ slots, those checks become really laggy :)

rhelgeby
01-02-2012, 15:57
Since the environment is single threaded, no. It will just delay the huge work.

What exactly are you checking?

If you're working with databases you should use threaded queries. You can also cache values where possible so you don't need to calculate them over and over again. But the probably most important is how efficient your code is, and if it can be done more efficient.

MindeLT
01-02-2012, 19:27
I'm re-writing it now. Deleting some unnecessary checks, and reducing the size of the code :)

rhelgeby
01-03-2012, 08:20
This doesn't look like expensive code to me. All you do is check and compare numbers.

One thing you could improve is to move the FindSendPropOffs line outside the event (to OnPluginStart or something). Though, the docs says that this value is cached.

You could use the SourceMod profiler (http://wiki.alliedmods.net/SourceMod_Profiler) to find out how much time that's spent in each part in your plugin. Open sourcemod/configs/plugin_settings.cfg. Add a section for your plugin or use the global section (*). In the section, add this line in "options":

"profile" "7"

Then play for some rounds (with players, not bots since you use !IsFakeClient). Do "sm profiler flush" in the server conrolse (or through rcon). A profile log is written in the sourcemod/logs directory. Open the file with profviewer.exe (in SourceMod downloads page).

Find out which functions that are called a lot and have highest average times. Startup events like OnPluginStart may be high, but is only called once or a few times, so that's ok.

How much time do SourceMod plugins have? A server running at 66 ticks have about 15 ms frame time. The engine probably use 50% of that time, so then all plugins have about 7 ms frame time in total.

Busy function calls with average time higher than 7 ms should definitely be considered for optimization.

I bet the code you posted use less than one millisecond on average. A profile log from the Zombie:Reloaded plugin show that the spawn event is called more than 3000 times with a average time at 0.9 ms. That code probably do twice as much as your code, so your code should be safe.

If you can't see any high numbers in your plugin, it might be other plugins that slow down your server - or you might have too many plugins enabled at once.

Silvers
01-03-2012, 08:56
You could also replace the GetConVarInt. Instead use a variable which is read OnConfigsExecuted(). In OnPluginStart() do HookConvarChange() on that cvar. That would reduce CPU slightly in your callback.

rhelgeby
01-03-2012, 10:51
Yeah, reducing native calls help sometimes, but stuff like IsClientConnected and GetConVarInt are trivial. They probably cost less than a microsecond alone. If you're reading these values in a loop it might be worth caching it outside the loop, though.

But I don't think this block of code posted have any expensive operations. I recently did a performance test with dynamic function calling within a plugin (attached). The average overhead for a dynamic function call was around 250-450 ns compared to 10 ns for a static function call. Even though the difference is big, we're still only talking about nanoseconds.

Everyone should try the profiler on their plugins to see how well their code is performing.

My test plugin for dynamic calls:

MindeLT
01-03-2012, 12:27
Thank you both, for sharing your knowledge!
Gonna try these soon :)

MindeLT
01-03-2012, 18:49
Here's my new VIP system report.

http://eurocss.lt/images/loads_vip.PNG

rhelgeby
01-03-2012, 19:36
Close the profiler before opening a new file. It doesn't clear the list and you get duplicates. Also, these numbers doesn't look like usual. Did you convert these numbers? According to the profiler, the profile duration is 60 years...

It's easier to just upload the original xml-file. :P

MindeLT
01-03-2012, 20:00
Updated :3
http://eurocss.lt/images/loads_vip.PNG

Forum restrictions do not allow to upload .xml files.

rhelgeby
01-03-2012, 20:11
Just zip it. Is this the original unmodified log? It still have a profile duration of 60 years. I wouldn't trust these numbers. :P

MindeLT
01-03-2012, 20:31
I haven't modified anything. It's original log :)

P.S Uploaded .xml :3

rhelgeby
01-04-2012, 06:20
Ok. The numbers in your screenshot is displayed as microseconds for some reason.

Your EventPlayerSpawn callback has a average time of 562 µs, which itself is pretty good. I forgot to take into consideration that this is called once per player. With 50 players it will require a total average time of 28 ms, so yeah, it will delay two frames alone when the round starts and everyone is spawning at once.

To not delay a frame you'd need to keep it below about 140 µs (7ms / 50 players). Try cache the value from FindSendPropOffs in a global variable. You can do this in OnPluginStart.

The question is whether that callback is worth optimizing. When the round starts a lot is happening anyways and in most cases people won't notice two delayed frames. However, if all plugin authors think like this, all player spawn callbacks in all plugins might make a significant delay.

EventWeaponFire: If 50 players fire 10 bullets/sec constantly this callback will use 37 ms in total average. If the server is a deathmatch server or something with huge amounts of ammo you might want to look at this callback too.

Otherwise the numbers look good. All your callbacks except two stay below one millisecond on average.

MindeLT
01-04-2012, 06:58
Thank you once more for explaining everything so detailed!
In my opinion, these notes should go to Wiki. :3