LSL limitation for centralised game status tracking in real time (i.e. within 2-3 sec
|
|
Greg Hauptmann
Registered User
Join date: 30 Oct 2005
Posts: 283
|
02-15-2006 15:19
Hi,
I'm finding it very difficult getting a centrallised controller script which receives events from objects/contestants (say 1 event per 1-5 seconds) to perform it's operation in real time (i.e. within 2-3 seconds accuracy). It seems to fall behind, with events that start to queue up in the script. It still seems to work ok its just that its not always really up-to-date within 2-5 seconds (i.e. sometime the delay builds up to 10-20 seconds). The controller determines status and informs the contestant of their current ranking, so it is this update to the user I'm trying to get more realtime. Some details:
Event=>Controller: Roughly 2 second delay - using chat protocol within a small framework Controller Event Handler: Only 2 seconds with light load, but under load this increases to 10-20 seconds for example, and it seems like the events are queuing up.
The event handling routines may have 10 or so LSL lines in it, a fair portion of which include list functions (finds, updates etc), to do things like: is user registered, is it a valid event, what is their current status, is the event rx'ed expected, update their status, pass status update back to user. I'm assuming this code needs to be sychronized (i.e. only in one script, only one event at a time) as its updating global list-of-users type LISTs. This being the case the event code is already reasonably optimised so I'm not sure I can do much more for it.
So I guess my question is whether the respnose times I'm seeing are a fundamental LSL response time issue here? Any ideas?
Thanks heaps in advance
|
|
Ziggy Puff
Registered User
Join date: 15 Jul 2005
Posts: 1,143
|
02-15-2006 15:38
Maybe think about partitioning yoru data in a different way (multiple data-server type scripts and link messages, maybe?) to reduce the size of the lists. List lookups are pretty inefficient (O(n^2), I think), so if your list grows pretty large, your performance will drop pretty significantly. That could be one factor that's affecting you.
|
|
Greg Hauptmann
Registered User
Join date: 30 Oct 2005
Posts: 283
|
02-15-2006 16:20
Some more info: this lists themselves were quite small in the test - e.g. 4 x 2 strides = 8 items, but there are 4 or 5 lists. I already have broken out much of the functionality across multiple scripts, but the central status/workflow controller needs access to these 4-5 key lists. Some of the remote points sending events into the controller may be 10-90m away hence the use of chat.
|
|
Ziggy Puff
Registered User
Join date: 15 Jul 2005
Posts: 1,143
|
02-15-2006 16:43
Hmm... 8 items shouldn't be that bad. How are you determining how long things are taking? Do you have llSays scattered around the scripts which print a global timestamp (like wallclock time) along with information on what code is being executed?
|
|
Greg Hauptmann
Registered User
Join date: 30 Oct 2005
Posts: 283
|
02-15-2006 17:55
ummm..yes - I have log statements which does print out the time/scriptname/severity/log details. Plus on some methods I store time (llGetTimestamp) at the top so I can then log the duration for the method/event at the bottom when leaving. Taking out logging I know would help a bit, but I was assuming it wouldn't be an order of magnitude (?)
|
|
Strife Onizuka
Moonchild
Join date: 3 Mar 2004
Posts: 5,887
|
02-15-2006 18:21
I developed this method for comms an age ago. If your game is turn based or doesn't need it's updates to happen at exactly the same time as the device updates. You can use llKey2Name. Store your information in the name of some secondary prim of your game peices. Then when ever you want to update the score board just pole the key. This would work great on Tringo. It's also scaleable, as any number of displays can be reading the data without generating tons of events. Course this only works in the sim. list rankings;
vector zv = ZERO_VECTOR; //faster to do this.
default { state_entry() { llListen(-1943,"","",""); llSetTimerEvent(2); } listen(integer a, string b, key c, string d) { key e = llGetOwnerKey(c); if(1 + a = llListFindList(rankings,[e])) rankings = llDeleteSubList(rankings, a - 2, a); if((b = llKey2Name(d)) == "") { if(e == llGetOwnerKey(d)) { if(llGetAgentSize(e) != zv) { rankings += [(integer)b, d, e];//we store d as a string so only agent keys are keys, this will keep the two seperate in llListFindList. } } } } timer() { integer a = -llGetListLength(rankings); string b; while(a) { b = llKey2Name(llList2Key(rankings,a + 1)); if(b == "" || llGetAgentSize(llList2Key(rankings,a + 2)) == zv) llDeleteSubList(rankings, a, a + 2); else rankings = llListReplaceList(rankings,[(integer)b],a,a); a +=3; } rankings = llListSort(rankings, 3, FALSE); //Insert your update function to update board here. } }
_____________________
Truth is a river that is always splitting up into arms that reunite. Islanded between the arms, the inhabitants argue for a lifetime as to which is the main river. - Cyril Connolly
Without the political will to find common ground, the continual friction of tactic and counter tactic, only creates suspicion and hatred and vengeance, and perpetuates the cycle of violence. - James Nachtwey
|
|
Greg Hauptmann
Registered User
Join date: 30 Oct 2005
Posts: 283
|
02-19-2006 01:32
Hi Strife - I know I should probably just sit down and go through your code closely to work this out for myself  , but.........do you think you could post a few extra words on the intended usage of the calls in your code? Maybe variable name meanings could help too. I'm trying to work out whether your suggestion would really only help in improving inter-object comms, whereas my problem is really in the fundamental design limitation of my central controller (and its speed) which has synchronised code which should/can only be accessed by one caller at any time (i.e. and then because this takes a few seconds, the queue items waiting seems to start to build up) Tks
|
|
Strife Onizuka
Moonchild
Join date: 3 Mar 2004
Posts: 5,887
|
02-19-2006 04:02
ok what the script does, is listens for the key of an object, said on a specific chat channel. then once every 2 second it polls it's list of object keys, validates that the user is still in the sim, updates the score, and resorts the list. After the list is sorted you can do what you want with it. its a tracking system, for multiple objects which keep thier own scores. integer score; llSetObjectName((string)score); llSay(-1943,llGetKey());
_____________________
Truth is a river that is always splitting up into arms that reunite. Islanded between the arms, the inhabitants argue for a lifetime as to which is the main river. - Cyril Connolly
Without the political will to find common ground, the continual friction of tactic and counter tactic, only creates suspicion and hatred and vengeance, and perpetuates the cycle of violence. - James Nachtwey
|
|
Argent Stonecutter
Emergency Mustelid
Join date: 20 Sep 2005
Posts: 20,263
|
02-19-2006 07:44
From: Strife Onizuka 1 + a = llListFindList(rankings,[e]) You're kidding. That works without putting the assignment in parentheses?
|
|
Osgeld Barmy
Registered User
Join date: 22 Mar 2005
Posts: 3,336
|
02-19-2006 11:46
yup 
|
|
Strife Onizuka
Moonchild
Join date: 3 Mar 2004
Posts: 5,887
|
02-19-2006 11:49
pays to know your LSL order of operations. In complex equations i'll use parentheses. Really depends how sure I am of how LSL will order the operations. Simple stuff like this i'll be lazy.
_____________________
Truth is a river that is always splitting up into arms that reunite. Islanded between the arms, the inhabitants argue for a lifetime as to which is the main river. - Cyril Connolly
Without the political will to find common ground, the continual friction of tactic and counter tactic, only creates suspicion and hatred and vengeance, and perpetuates the cycle of violence. - James Nachtwey
|
|
Greg Hauptmann
Registered User
Join date: 30 Oct 2005
Posts: 283
|
02-19-2006 12:33
thanks Strife (this assignment threw me too when I perused through the code previously  )
|
|
Strife Onizuka
Moonchild
Join date: 3 Mar 2004
Posts: 5,887
|
02-19-2006 12:53
From: Greg Hauptmann thanks Strife (this assignment threw me too when I perused through the code previously  ) yeah i have a few bad coding habbits. I sacrifice a level of readability for a bit of speed and i use letter variable names (but rarely for globals).
_____________________
Truth is a river that is always splitting up into arms that reunite. Islanded between the arms, the inhabitants argue for a lifetime as to which is the main river. - Cyril Connolly
Without the political will to find common ground, the continual friction of tactic and counter tactic, only creates suspicion and hatred and vengeance, and perpetuates the cycle of violence. - James Nachtwey
|
|
Val Fardel
Registered User
Join date: 11 Oct 2005
Posts: 90
|
02-22-2006 09:04
Out of curiosity why do you think using an assignment of zv = ZERO_VECTOR instead of ZERO_VECTOR is faster in the compiled code? It's a vector value so it isn't going to be assigned to an individual processor register...
|
|
Strife Onizuka
Moonchild
Join date: 3 Mar 2004
Posts: 5,887
|
02-22-2006 10:03
It's because it takes less time to copy a vector already in memory into the stack then to read one from the script bytecode and copy it into the stack. That probably didn't help any... LSL is notoriously inefficiant. As to why exactly i do not know.
_____________________
Truth is a river that is always splitting up into arms that reunite. Islanded between the arms, the inhabitants argue for a lifetime as to which is the main river. - Cyril Connolly
Without the political will to find common ground, the continual friction of tactic and counter tactic, only creates suspicion and hatred and vengeance, and perpetuates the cycle of violence. - James Nachtwey
|
|
Argent Stonecutter
Emergency Mustelid
Join date: 20 Sep 2005
Posts: 20,263
|
02-22-2006 17:24
I'm sorry, Strife, I can't do some of that stuff. I've got 30 years of experience of having compilers break working code that depended on things a lot more obscure than the order of evaluation of arguments in functions. I understand your reasoning for LL not breaking existing code, but they could easily set things up so that existing scripts will coontinue to work but you'll need to redo your code to get it to recompile in Mono.
And... that missing set of parens... *brrrr*.
|
|
Eggy Lippmann
Wiktator
Join date: 1 May 2003
Posts: 7,939
|
02-22-2006 18:00
From: Strife Onizuka You can use llKey2Name. Oh. My. God. Why didn't you tell me this BEFORE!!!  Will you marry me? *bats eyelashes*
|
|
Strife Onizuka
Moonchild
Join date: 3 Mar 2004
Posts: 5,887
|
02-22-2006 18:34
From: Eggy Lippmann Oh. My. God. Why didn't you tell me this BEFORE!!!  Will you marry me? *bats eyelashes* *shrug* nobody ever asked. The code i thought it up in is publicly available on my other website along with a mod version of XyCalc. MailerDaemonThough it's pretty far embedded in the scripts, and i wrote the scripts while i was still pretty green at scripting in LSL. So the scripts are... very unreadable i'm betting. (it's in the Strife Combat System). Alot of stuff i thought up for it, i still use in one form or another. TightList was born at that time (functions labled parse & dump). Float2Sci was born around then (though now i use Float2Hex, much faster and without the hastle of base 10; not as smart a function though). Also a cool ESL header file so i don't have to copy and paste in Copyright notices (it writes them based on #defines) Never finished the combat system, project just fell apart. It isn't much fun when you're the only scripter on a project and nobody to bounce ideas off.
_____________________
Truth is a river that is always splitting up into arms that reunite. Islanded between the arms, the inhabitants argue for a lifetime as to which is the main river. - Cyril Connolly
Without the political will to find common ground, the continual friction of tactic and counter tactic, only creates suspicion and hatred and vengeance, and perpetuates the cycle of violence. - James Nachtwey
|
|
Christopher Omega
Oxymoron
Join date: 28 Mar 2003
Posts: 1,828
|
02-22-2006 19:47
From: Eggy Lippmann Oh. My. God. Why didn't you tell me this BEFORE!!!  Will you marry me? *bats eyelashes* Dude, its been discussed in the past on the wiki - even documented in AlternativeCommunications. Though I commend Strife for finding a good use for it in practice. Ill add this scenerio to that page as soon as I have the free time to.  ==Chris
|
|
Sky Honey
Coder
Join date: 16 May 2005
Posts: 105
|
02-23-2006 07:02
From: Christopher Omega Though I commend Strife for finding a good use for it in practice. Ill add this scenerio to that page as soon as I have the free time to.  ==Chris Good idea Chris, Strife's example shows that llKey2Name is more useful than AltenativeCommunications implies. But that negative list index thing he does is just wierd 
|
|
Strife Onizuka
Moonchild
Join date: 3 Mar 2004
Posts: 5,887
|
02-23-2006 10:11
From: sky Honey Good idea Chris, Strife's example shows that llKey2Name is more useful than AltenativeCommunications implies. But that negative list index thing he does is just wierd  By using a negative index, i save a variable, which means one less variable i have to keep track of. Negitive indexs count from the other end of the list or string (except for llInsertString where LL forgot to add it, and i'm currently badgering them to add). So -llGetListLength() is the first index. We use the value. Then we add to it's value till it hits zero. As long as our list isn't corrupted all is well.
_____________________
Truth is a river that is always splitting up into arms that reunite. Islanded between the arms, the inhabitants argue for a lifetime as to which is the main river. - Cyril Connolly
Without the political will to find common ground, the continual friction of tactic and counter tactic, only creates suspicion and hatred and vengeance, and perpetuates the cycle of violence. - James Nachtwey
|
|
Eggy Lippmann
Wiktator
Join date: 1 May 2003
Posts: 7,939
|
02-23-2006 10:11
Chris, remember that comms thing I was coding? Remember how it took a shitload of scripts to make email reasonably fast? We could have done it with Key2Name  *sigh* I wish Cory would get off his ass and give us that shared memory thingy he promised. Or Mono. Or something.
|
|
Sky Honey
Coder
Join date: 16 May 2005
Posts: 105
|
02-23-2006 12:42
From: Strife Onizuka By using a negative index, i save a variable, which means one less variable i have to keep track of. Negitive indexs count from the other end of the list or string (except for llInsertString where LL forgot to add it, and i'm currently badgering them to add). So -llGetListLength() is the first index. We use the value. Then we add to it's value till it hits zero. As long as our list isn't corrupted all is well. Thanks for explaining it Strife, it makes more sense to me now. It threw me when I first read it until I saw that minus sign: integer a = -llGetListLength(rankings);
|