Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

How To: multiple virtual timers with 1 timer event

Seronis Zagato
Verified Resident
Join date: 30 Aug 2005
Posts: 454
05-31-2006 12:07
I've caught several conversations in-world and see a few threads with people needing to use multiple timers in a script but fearing the possible lag of having mulitple scripts running timers. Well here is a method you can use where a single timer() event can execute several different features all at different intervals.

CODE

float FREQUENCY = 0.25; //we have 4 timer pulses per second base

//we need 1 counter and 1 interval defined per virtual timer
integer tCounter1 = 0;

//these are the intervals each virtual timer will trigger at
//time interval is equal to integer value * timer frequency
integer INTERVAL_1 = 2; // half second
integer INTERVAL_2 = 4; // one second
integer INTERVAL_3 = 60; // 15 secs
integer INTERVAL_4 = 240; // 1 min

default {
state_entry() {
llSetTimerEvent( FREQUENCY );
}

timer( )
{
++tCounter; // increment counter

if( tCounter % INTERVAL_1 == 0 ) {
//perform actions for virtual timer 1
}
if( tCounter % INTERVAL_2 == 0 ) {
//perform actions for virtual timer 2
}
if( tCounter % INTERVAL_3 == 0 ) {
//perform actions for virtual timer 3
}
if( tCounter % INTERVAL_4 == 0 ) {
//perform actions for virtual timer 4
}
}
}


If you need to execute scripts that are in totally seperate prims in the object you can have your virtual timer code blocks send specially formatted link messages to the script in question.
Joannah Cramer
Registered User
Join date: 12 Apr 2006
Posts: 1,539
05-31-2006 12:12
Seeing how this single timer runs at higher frequency and for larger total amount of impulses combined than 4 separate timers in this example would do otherwise, does it actually help at all to reduce lag, or is the end effect opposite? ^^;;
Rodrick Harrington
Registered User
Join date: 9 Jul 2005
Posts: 150
05-31-2006 13:32
with the research someone did with totally empty scripts and the lag it causes I would guess it's 6 in one half a dozen in the other.
_____________________
Tiger Crossing
The Prim Maker
Join date: 18 Aug 2003
Posts: 1,560
05-31-2006 13:47
In this example, the base frequency should be set to 0.5 and divide all the other timer values by 2. This would make the script twice as efficient without altering how often the triggers fire. When using a script like this, I suggest making the fastest timer always 1 to keep the efficiency as high as possible.

(I know this was just an example of a technique, but wanted to point this out...) :)
_____________________
~ Tiger Crossing
~ (Nonsanity)
Seronis Zagato
Verified Resident
Join date: 30 Aug 2005
Posts: 454
05-31-2006 14:05
And i was intentionally avoiding that technique because as a sim does lag one of the first thing to start getting skipped is timer events. The timer frequency there takes this into consideration so that when timer events ARE dropped it has a reduced effect. Its the difference between a tiny self correcting delay and completely skipped processing.

As for the total number of events effeciency issue the reason it becomes more effecient is because the lag isnt from how many events are triggered only (meaning the frequency alone). In this example the actual processing done in the event itself is limited to incrementing an integer so thats not bad (for the benifit of greater accuracy).

The lag potion comes from the behind the scenes sceduling involved. In my example there is only a single timer object allocated in memory controlling the event. There is only one object that gets checked to see if its ready for scheduleing or not. Its all the behind the scenes aspects that add up as you have a large NUMBER of timers scheduled that causes the slowdown.

Another way to put it, is each sim frame (fps) that executes has to cycle the entire list of timer events. It takes some minimal processing power to cycle thru each item. It takes a bit more processing as on each registered timer it has to compare the timestamps on them to see which ones are due to execute. If the sim is lagging behind its even more processing to analyze which tiemr events are the best to skip processing on. Thats why with a slightly higher number of total events being sent its still more effecient.

You also have instances where you might need a lot of high freqency operations performed with only a few low ones. In those cases this method will also result in fewer total events executing which is optimal in all regards. An example of this would be if you needed 5 pseudo timers with intervals of 1,1,2,2,60.
Joannah Cramer
Registered User
Join date: 12 Apr 2006
Posts: 1,539
05-31-2006 14:35
From: Seronis Zagato
The lag potion comes from the behind the scenes sceduling involved. In my example there is only a single timer object allocated in memory controlling the event. There is only one object that gets checked to see if its ready for scheduleing or not. Its all the behind the scenes aspects that add up as you have a large NUMBER of timers scheduled that causes the slowdown.

Another way to put it, is each sim frame (fps) that executes has to cycle the entire list of timer events. It takes some minimal processing power to cycle thru each item. It takes a bit more processing as on each registered timer it has to compare the timestamps on them to see which ones are due to execute.

OK, but then isn't your code doing essentially the very same thing the server-based timer scheduler does... except implementing it in slow much much slower script instead of letting pre-compiled and optimized server code handle it? I mean, if you schedule 4 timers then the server does the very same thing you do -- walk the list, check if it's time to fire the event, and depending on the result either does it, or not. There is no reason to expect that server code does the checks if it's time to execute events ... any less efficiently than this code, after all? o.O;

(this isn't to say it's useless code because i definitely can see some nice uses for it... just not sure i can see where this whole extra efficiency thing when compared to server based timers comes from ^^;
Argent Stonecutter
Emergency Mustelid
Join date: 20 Sep 2005
Posts: 20,263
05-31-2006 17:54
If you use the following technique you won't miss timers... it'l catch up even multiple missed events.

CODE

state_entry()
{
float now = llGetTime();
next_time_1 = now + frequency_1;
next_time_2 = now + frequency_2;
//...
llSetTimerEvent(greatest_common_divisor_of_frequencies);
}

timer()
{
float now = llGetTime();
if(now > last_time + greatest_common_divisor_of_frequencies * 10) {
// Whoops, we got delayed a REAL long time, let's go back to home base...
llResetScript();
}
last_time = now;
if(now > next_time_1) {
event_1();
next_time_1 += frequency_1;
}
if(now > next_time_2) {
event_2();
next_time_2 += frequency_2;
}
//...
}
Seronis Zagato
Verified Resident
Join date: 30 Aug 2005
Posts: 454
05-31-2006 18:01
Well considering LSL compiles down to a bytecode that implies its in an executable form (as compared to interpreted at runtime). So in my version i dont have all the various function calls used for doing the comparisons and just a simple integer check. I dont have to increment any object pointers to cycle between my lines. And its a slightly reduced memory footprint server side (though fully counts against my scripts 16kb limit).

So the effeciency comes from those backend operations. If your programming experience is in java languages you might not understand all the memory specifics but if its in C or C++ where you have to manually perform your allocations and dont have automatic smart pointers you are more likely to understand where the *minor* speed improvement comes from.

Also to note this method has no real benifit to the scripters themselves. It doesnt make your scripts 'faster'. What it does do is create a small effeciency gain to the sim by potentially reducing the number of cpu cycles required to execute your scripts.
Seronis Zagato
Verified Resident
Join date: 30 Aug 2005
Posts: 454
05-31-2006 18:05
Argent, perfect code except its not accomplishing the goal i was fulfilling. Increasing EFFECIENCY, not nessisarily security of events. The frequency i choose by being half the fastest frequency was strictly to 'reduce' the potential effects of missed timer events and not to totally remove the effect completley by requiring MORE intensive evaluations.

But its great code for the task its fulfilling !

=-)