Register to post in forums, or Log in to your existing account
 

Play RetroMUD
Post new topic  Reply to topic     Home » Forums » CMUD Beta Forum
Vijilante
SubAdmin


Joined: 18 Nov 2001
Posts: 5182

PostPosted: Sat Nov 03, 2007 6:51 pm   

[2.10] Triggers can get slower
 
I started noticing this when trying to test the locking issue with 2.09. Let me start by saying that the test method here shows 1 bug and another optimization issue, but I am really only concerned by the bug displayed in these 2 timed tests. I know this is another of my 'extreme' tests. Once triggers change in this fashion they tend to stay slower.
Code:
110 create time 3460
test 0
Time compile 528
test 1000
Time 2000 clean 231
112 create time 3186
test 0
Time compile 1536
test 1000
Time 2000 clean 1139


I will explain the optimization issue as well, even though that is secondary. The optimization issue is caused by the background package updates, this test contiuously makes it worse. So hopefully you can find the cause of the change in trigger behavior before the background updates start taking over 1 minute to complete. It seems that the main cause of this massive slow down is due to the continuously growing amount of memory the test causes CMud to use. It also causes a final save of the package when hitting the big X to become equally slow and causes the package to remain in use for a while after CMud appears to close. It seems a second save of the package goes on for an equal period of time. This also results in some hideously large package files full of junk.

Procedure
1. Launch CMud
2. Close Sessions window (ESC)
3. Enter at the command line
Code:
#VAR count 0;#ALIAS time {#ADD count 1;#VAR $t1 {%secs};#DELCLASS ttest;#VAR a 0;#LOOP 1000 {#EXEC {%concat("#TRIGGER ",%char(34),%i,%char(34)," {test} {#ADD a 1} {ttest}")}};#SHOW @count create time (%secs-$t1);#VAR $t1 {%secs};#SHOW test @a;#SHOW Time compile (%secs-$t1);#VAR $t1 {%secs};#SHOW test @a;#SHOW Time @a clean (%secs-$t1)}


Now if you want to see the background updating get bad very fast do this at the command line
Code:
#LOOP 100 {time}

In order to see what I think is a bug with triggers I do this
Code:
#WAITSIGNAL dotime;#LOOP 100 {time}
then in a seperate entry #SIGNAL dotime.

If have seen the triggers change speed as early as the 34th itteration, but you may have to extend the loop to spot it. I have also seen them go back to full speed for a few passes after they went slow. As long as I let it run though they tended to stay slow once they have become slow.

When I initially noticed 'something odd' with 2.09 the slowdown of the triggers tended to happen rather quickly, and tended to keep getting worse. I haven't run the test long enough to find out if 2.10 will do the same thing mainly because the background updating tends to bring CMud to a grinding halt after about 180 itterations on my system.

I started to test with #TEMP instead of #TRIGGER, but I did not get any conclusive results yet. Other then they can still cause the background updates to climb rather quickly.
_________________
The only good questions are the ones we have never answered before.
Search the Forums
Reply with quote
Fang Xianfu
GURU


Joined: 26 Jan 2004
Posts: 5155
Location: United Kingdom

PostPosted: Sat Nov 03, 2007 7:28 pm   
 
You were a bit vague about the issues you were reporting here, so I could've misunderstood, but I saw no bug with the #waitsignal. I also saw no slowdown as the script continued. Four of them were delayed - one create was about 5s, two creates were about 15s, and one compile was 20s - but my test wasn't exactly stringent. The rest were very much at the median, 1300/700/1100.

If "the numbers get bigger" wasn't the issue you were reporting, please be a bit more specific. And I have no idea what your bug with #waitsignal was.
_________________
Rorso's syntax colouriser.

- Happy bunny is happy! (1/25)
Reply with quote
Fang Xianfu
GURU


Joined: 26 Jan 2004
Posts: 5155
Location: United Kingdom

PostPosted: Sat Nov 03, 2007 7:38 pm   
 
I reread your post and get the feeling that my report does back up your slowdown claims. I went back to check this when I went to close CMUD and my god, it took an age to close. I was trying to see if it was cache thrashing or using 100% cpu, but by the time I thought to check, it had closed. Definintely something here.

About the #waitsignal thing, though, I'm clueless.
_________________
Rorso's syntax colouriser.

- Happy bunny is happy! (1/25)
Reply with quote
Arde
Enchanter


Joined: 09 Sep 2007
Posts: 605

PostPosted: Sat Nov 03, 2007 8:07 pm   
 
Vijilante, I ran your script with #LOOP 100 {time}. After 8th iteration CMUD crashed with "insufficient quota to execute a command" message or like. Create time raises steady by 400 with each iteration, compile time at 6/7/8th steps was 912/998/2479
_________________
My personal bug|wish list:
-Wrong Priority when copy-paste setting
-1 prompt trigger for Mapper, Session and General Options, not 3 different!
-#SECTION can terminate threads
-Buttons can't start threads
Reply with quote
Vijilante
SubAdmin


Joined: 18 Nov 2001
Posts: 5182

PostPosted: Sat Nov 03, 2007 9:13 pm   
 
Using the #WAITSIGNAL and #SIGNAL is just a method to put the entire #LOOP 100 {time} into a background thread cleaner than hitting SHIFT-ESC. Those work perfectly.

If you examine the output snippet I included you will see that the time for the testing of the triggers increased evenly by about 900ms. That is the portion that looks to be a bug. Also from that ouput snippet you will see that I had to run the loop up over 110 times, as I say I have seen that particular time increase much sooner.

Any of the huge time jumps, and the massive delay when closing are caused by the background package updates. The only possible way I can see them becoming a problem in normal usage is if a script creates and fires at #TEMP triggers. It appears from the testing that I have done that it leaves something behind in the package file each time. This would mean that over the course of hours of play the background update could conceivably become a serious problem.

So there are 2 different tests presented, one glaringly highlights the background updates by having the #LOOP 100 {time} run in the main user thread. The other puts that loop into a background thread which lets things flow along better until the but with trigger execution time can be observed. Both tests have the same first 3 steps, then step 4 and step 5 determine which test you are doing. Sorry I didn't make it clearer, I was in a little bit of a rush.

Arde That is interesting, I can run that foreground loop test quite a bit further. I never ran it out enough to get a crash and the times involved are quite a bit different. Again something that appears a matter of system specs. Mine are floating all over the board in numerous crash dumps I have posted. Having yours might be interesting if no one else finds anything. Also I will take some time to run the foreground loop test out to a crash, although I shudder at the thought of how long it might take.
_________________
The only good questions are the ones we have never answered before.
Search the Forums
Reply with quote
Fang Xianfu
GURU


Joined: 26 Jan 2004
Posts: 5155
Location: United Kingdom

PostPosted: Sat Nov 03, 2007 9:28 pm   
 
@Arde: 8 is rather low, but consider that during the course of that, CMUD has created and deleted 8000 triggers. That's quite a lot - if you've not got much RAM, I can see that many triggers being a problem.

@Viji: You only posted two loop iterations, and two got slower and one got faster. It was hard to tell just from that what you were highlighting as the problem. Regardless, I didn't see any slowdown over the iterations - they were all the same. The only slowdowns I saw were the background updates.

On that topic, I'm really not surprised that the background thread takes so long. When you consider that the test creates at least one hundred thousand triggers, it's hardly surprising that the background thread takes a while. I'd assume that it only saves things that're flagged as changed, and that's a lot of items that're marked as changed and need to be written to disk. I had the thread update about once every 30k triggers, which is still rather a lot :|
_________________
Rorso's syntax colouriser.

- Happy bunny is happy! (1/25)
Reply with quote
Arde
Enchanter


Joined: 09 Sep 2007
Posts: 605

PostPosted: Sat Nov 03, 2007 10:27 pm   
 
Ran 1st script (foreground loop) again, now it lasted for 9 loops. Here is the timings
Code:

1 create time 1413
test 0
Time compile 269
test 1000
Time 2000 clean 147
2 create time 1967
test 0
Time compile 260
test 1000
Time 2000 clean 126
3 create time 2418
test 0
Time compile 265
test 1000
Time 2000 clean 139
4 create time 2856
test 0
Time compile 279
test 1000
Time 2000 clean 136
5 create time 3301
test 0
Time compile 267
test 1000
Time 2000 clean 146
6 create time 3757
test 0
Time compile 270
test 1000
Time 2000 clean 144
7 create time 4260
test 0
Time compile 307
test 1000
Time 2000 clean 146
8 create time 4791
test 0
Time compile 278
test 1000
Time 2000 clean 159
9 create time 5470
test 0
Time compile 318
test 1000
Time 2000 clean 161
<CRASH>

Main ($212c):
00c86594 +0038 cMUD.exe     MAIN        1019   +4 APICheck
00c8c5a6 +1232 cMUD.exe     MAIN        2737 +364 TMUDForm.ProcessMUDBuffer
00cc07b4 +4618 cMUD.exe     MAIN       17119 +732 HandleCase
00cc6d3f +007f cMUD.exe     MAIN       18181  +11 TMUDForm.ExecCommand
00c4b1ac +0034 cMUD.exe     CodeThread  1076   +2 TRunCodeThread.DoExecCommand
0047d901 +0101 cMUD.exe     Classes     9339  +22 CheckSynchronize
00c4a3dc +00c4 cMUD.exe     CodeThread   445  +25 MsgWaitForSingleObject
00c4a4fd +0029 cMUD.exe     CodeThread   510   +4 WaitForThread
00c97c52 +012e cMUD.exe     MAIN        6005  +32 TMUDForm.ExecThread
00c987e2 +03c6 cMUD.exe     MAIN        6213  +44 TMUDForm.NewProcessStr
00c977be +0026 cMUD.exe     MAIN        5899   +2 TMUDForm.ProcessStr
00c9729a +004a cMUD.exe     MAIN        5774  +12 TMUDForm.ParseCommand
00ca5be3 +0223 cMUD.exe     MAIN       11189  +34 TMUDForm.Command
00ca6f14 +0250 cMUD.exe     MAIN       11538  +37 TMUDForm.FormKeyDown
00ccdf26 +0012 cMUD.exe     MAIN       20058   +1 TMUDForm.UserInKeyDown
0050b5a0 +0030 cMUD.exe     Controls    7026   +1 TWinControl.KeyDown
009aa1be +0012 cMUD.exe     RVScroll     548   +1 TRVScroller.KeyDown
00958dc5 +0011 cMUD.exe     RichView    1842   +1 TCustomRichView.KeyDown


System specs I posted once... well a long time ago. Here they are (from bugreport.txt)

Code:

operating system  : Windows XP Service Pack 2 build 2600
system up time    : 11 hours 58 minutes
processors        : 2x Intel(R) Pentium(R) D CPU 3.40GHz
physical memory   : 1371/2046 MB (free/total)
free disk space   : (D:) 68,37 GB
display mode      : 1680x1050, 32 bit
allocated memory  : 45,08 MB
Reply with quote
Arde
Enchanter


Joined: 09 Sep 2007
Posts: 605

PostPosted: Sat Nov 03, 2007 10:37 pm   
 
I modified Vijilante' step 3 script and add #THREAD command to its tail. I can see increasing number of stopped threads with each loop, up to 12-15 of them. If choose to continue application after the crash, it may reduce number of stopped threads or may not to do so... Heh, loop 30, I have 38 threads...
_________________
My personal bug|wish list:
-Wrong Priority when copy-paste setting
-1 prompt trigger for Mapper, Session and General Options, not 3 different!
-#SECTION can terminate threads
-Buttons can't start threads
Reply with quote
Vijilante
SubAdmin


Joined: 18 Nov 2001
Posts: 5182

PostPosted: Sat Nov 03, 2007 11:37 pm   
 
I am not that concerned about the background updating. It takes about 2k triggers created and destroyed to add 1 second to that on my system, and my final test of reloading the package into a fresh launch shows that delay caused there is reset with each launch. The only way it could be an issue is if someone leaves CMud open continuously and uses a fairly large number of #TEMP triggers or #UNVAR. I guess knowing about it and the way in which it causes a periodic 100% CPU pause only is the only use of having found it. It lets us give better support and advice.

Obviously the crash isn't good, but it is caused by having the test in the foreground main thread. This is the same crash that the test done with 2.09 would cause. Look at Zugg's notes there.

In terms of the part I consider a bug I may have to just forget about it because it is very hard to replicate, and virtually impossible to cause in any normal usage. I will however post the full procedure and some final stats for consideration.

1. Launch CMud
2. Close Sessions window (ESC)
3. Enter at the command line
Code:
#VAR count 0;#ALIAS time {#ADD count 1;#VAR $t1 {%secs};#DELCLASS ttest;#VAR a 0;#LOOP 1000 {#EXEC {%concat("#TRIGGER ",%char(34),%i,%char(34)," {test} {#ADD a 1} {ttest}")}};#SHOW @count create time (%secs-$t1);#VAR $t1 {%secs};#SHOW test @a;#SHOW Time compile (%secs-$t1);#VAR $t1 {%secs};#SHOW test @a;#SHOW Time @a clean (%secs-$t1)}

4. Enter at the command line
Code:
#WAITSIGNAL dotime;#LOOP 200 {time}

5. Enter at the command line
Code:
#SIGNAL dotime


At this point I watch the numbers float by, go out for a smoke, look at some more numbers, check to see if anyone else posted an interesting bug, check back for some more numbers...Finally here is a rather lengthy section of the log. The numbers I am concerned about are the 'time compile' and the 'time clean', consider that some of the huge spikes do not show in the log, others by placement seem to cause odd times, and occasionally the time returns to normal for a short while.
Code:
175 create time 53917
test 0
Time compile 539
test 1000
Time 2000 clean 230
176 create time 3230
test 0
Time compile 532
test 1000
Time 2000 clean 229
177 create time 56673
test 0
Time compile 544
test 1000
Time 2000 clean 241
178 create time 3205
test 0
Time compile 550
test 1000
Time 2000 clean 327
179 create time 57900
test 0
Time compile 2241
test 1000
Time 2000 clean 54850
180 create time 3255
test 0
Time compile 1540
test 1000
Time 2000 clean 52796
181 create time 3260
test 0
Time compile 1513
test 1000
Time 2000 clean 1154
182 create time 53826
test 0
Time compile 1535
test 1000
Time 2000 clean 1164
183 create time 3202
test 0
Time compile 52128
test 1000
Time 2000 clean 227
184 create time 3195
test 0
Time compile 529
test 1000
Time 2000 clean 232
185 create time 3195
test 0
Time compile 541
test 1000
Time 2000 clean 53574
186 create time 3203
test 0
Time compile 1529
test 1000
Time 2000 clean 1155
187 create time 53693
test 0
Time compile 1513
test 1000
Time 2000 clean 1160
188 create time 3205
test 0
Time compile 51961
test 1000
Time 2000 clean 226
189 create time 3190
test 0
Time compile 885
test 1000
Time 2000 clean 1171
190 create time 55540
test 0
Time compile 1518
test 1000
Time 2000 clean 1167
191 create time 3196
test 0
Time compile 54134
test 1000
Time 2000 clean 1209
192 create time 3259
test 0
Time compile 54678
test 1000
Time 2000 clean 225
193 create time 3232
test 0
Time compile 528
test 1000
Time 2000 clean 239
194 create time 55964
test 0
Time compile 1061
test 1000
Time 2000 clean 1154
195 create time 3196
test 0
Time compile 54040
test 1000
Time 2000 clean 1200
196 create time 3224
test 0
Time compile 55115
test 1000
Time 2000 clean 226
197 create time 3207
test 0
Time compile 523
test 1000
Time 2000 clean 318
198 create time 55773
test 0
Time compile 1518
test 1000
Time 2000 clean 1145
199 create time 56136
test 0
Time compile 1527
test 1000
Time 2000 clean 1144
200 create time 3199
test 0
Time compile 55334
test 1000
Time 2000 clean 1199
test manual 2000
Time 228
test manual 3000
Time 225
test manual 4000
Time 228
test manual 5000
Time 224
test manual 6000
Time 224
test manual 7000
Time 231
test manual 8000
Time 228
test manual 9000
Time 232
test manual 10000
Time 224
no match manual 11000
Time 10
no match manual 11000
Time 9
no match manual 11000
Time 9
no match manual 11000
Time 9
no match manual 11000
Time 9
no match manual 11000
Time 10
no match manual 11000
Time 9
test manual 11000
Time 230
Threads:
  #   ID         Window Name          Status               Script                                 
  -------------------------------------------------------------------------------------------------
  2              [u] untitled         running              #THREAD                                 

The manual entries at the end were done with
Code:
#VAR $t1 {%secs};#SHOW test manual @a;#SHOW Time (%secs-$t1)
#VAR $t1 {%secs};#SHOW no match manual @a;#SHOW Time (%secs-$t1)


The final file size of the untitled package in this test was 425Kb
The final memory usage of CMud in this test was 189Mb with VM of 220MB

I think that pretty much is it unless someone finds a really convient way to cause similar time problems with triggers. I can't be sure that my flipping over to the forums and looking around did anything, and I can't be sure it didn't. Although I now have to track down a few other things and post a few other easy bugs that this spawned.
_________________
The only good questions are the ones we have never answered before.
Search the Forums
Reply with quote
Seb
Wizard


Joined: 14 Aug 2004
Posts: 1269

PostPosted: Sun Nov 04, 2007 3:38 am   
 
If you want to make sure that using other programs doesn't affect CMUD, one thing that will help is to open Task Manager and in the Processes list, locate the cMUD process that is using the most memory and set its priority to High (or just to Above Normal if you want to make sure you can still kill it via Task Manager, although there are other processes that might be running above normal - I think Winamp might, even though it doesn't appear to).
Reply with quote
Zugg
MASTER


Joined: 25 Sep 2000
Posts: 23379
Location: Colorado, USA

PostPosted: Mon Nov 05, 2007 5:49 pm   
 
I'll take a quick look into this, but keep in mind the same comments that I made in the other post. When you are running long loops from a command line or trigger like this, Windows is blocked from it's normal messaging during that execution (to prevent text from the MUD from being processed).

This causes lots of side effects. It causes memory usage to rise. It causes the Windows message queue to fill up (which is what causes the "insufficient quota" that Arde gets). It prevents CMUD from cleaning up any threads that are finished, and probably prevents CMUD from cleaning up the database, which could cause the long database update times that you are seeing.

The background thread for updating the *.pkg database on disk is not blocked from running. But while it is running, it has a lock on the database (you can't modify the database while it's being saved to disk...otherwise you'd get corrupted databases very easily).

I'll take look at the #WAITSIGNAL case since that should be running the loop in the background, which shouldn't cause these problems. However, when loops are running in a background thread, they "give up" their processor slice every 200ms. This allows other threads (and the main UI thread) to get their time. So this *can* cause a script to run slower in the background that it might in the foreground.

In more technical terms, a loop running in a background thread calls Sleep(0) every 200 ms or so. This tells Windows to run any other threads that are waiting.

In any case, while it was useful to find the problem with hanging threads, we should probably avoid a lot of stress-testing that involves really huge loops on the command line. Anything that takes more than a minute or so to execute should never be executed directly on the command line (remember, it's going to stop all response from the MUD during that time, and most people don't want to stop their MUD output for that long). This kind of testing is going to cause all sorts of red-herrings that do not impact normal operation.
Reply with quote
Llwethen
Novice


Joined: 08 Dec 2006
Posts: 37
Location: Lancaster,Oh

PostPosted: Tue Nov 06, 2007 3:54 am   
 
200 ms seems like an awful long time to let a process run unchecked.

New Linux and FreeBSD schedulers run much smaller values than that for good interactive performance. Windows XP uses 10 ms for it's job scheduler. Lower number might even help with concurrency reducing the starvation on other threads?

Dunno it might be fine my mind has been wrapped up in 8-bit microcontrollers and writting an entire program that has to run under 25 ms.
Reply with quote
Zugg
MASTER


Joined: 25 Sep 2000
Posts: 23379
Location: Colorado, USA

PostPosted: Tue Nov 06, 2007 5:38 am   
 
Yeah, but it's a tradeoff. With a value less than 200ms the background threads get a lot slower because they are context switching more. But it's definitely something I'll be fine-tuning over time.
Reply with quote
Seb
Wizard


Joined: 14 Aug 2004
Posts: 1269

PostPosted: Wed Nov 07, 2007 1:10 am   
 
Hmm, Llwethen has made me think of something - in a mud that doesn't implement a minimum delay between commands, 200 ms is a long time. Someone can come in and hit you before you even see them as the background thread is running and busy and the main thread hasn't updated the screen. That could be the difference between life and death.
Reply with quote
Zugg
MASTER


Joined: 25 Sep 2000
Posts: 23379
Location: Colorado, USA

PostPosted: Wed Nov 07, 2007 5:47 am   
 
This isn't a delay. What I mean is that if you have a script stuck in a long loop, the loop will give up it's time-slice every 200ms. So this only effects long-running background scripts. Also, this is just a "forced" way to give up a time-slice. Windows itself will already multi-task the multiple threads, so it's not like CMUD is going to sit there for 200 ms without responding to anything.

However, with that said, keep in mind that while any script is running on the command line (in the foreground), CMUD isn't going to accept any text from the MUD until the foreground script is finished. But this only happens when a foreground thread is running, not a background thread.
Reply with quote
Seb
Wizard


Joined: 14 Aug 2004
Posts: 1269

PostPosted: Wed Nov 07, 2007 11:05 am   
 
Yes, I was talking about long-running background scripts, but if the main thread will display new text and allow input that's OK. Maybe I'm getting up my own arse here since there aren't a whole lot of scripts that should take more than 200 ms.
Reply with quote
Display posts from previous:   
Post new topic   Reply to topic     Home » Forums » CMUD Beta Forum All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

© 2009 Zugg Software. Hosted by Wolfpaw.net