On my unix vm, Delay wakeups often happen a lot later than requested if the idle process kicks in. Craig provided a bit of code from spoon that fixes this issue: http://bugs.squeak.org/view.php?id=7652 |
On 15.07.2011, at 01:40, Matthew Fulmer wrote: > > On my unix vm, Delay wakeups often happen a lot later than requested > if the idle process kicks in. Craig provided a bit of code from spoon > that fixes this issue: > http://bugs.squeak.org/view.php?id=7652 Very interesting. On John's 4.x Mac VM I get 990 wakeups/sec. Same for John's 5.7.4, 990/s. But 5.8, and recent Cog/Stack VMs only do < 500 wakeups/sec. Both Carbon and Cocoa versions. - Bert - |
Bert Freudenberg wrote: > > On 15.07.2011, at 01:40, Matthew Fulmer wrote: > > >> On my unix vm, Delay wakeups often happen a lot later than requested >> if the idle process kicks in. Craig provided a bit of code from spoon >> that fixes this issue: >> http://bugs.squeak.org/view.php?id=7652 >> > > Very interesting. > > On John's 4.x Mac VM I get 990 wakeups/sec. > > Same for John's 5.7.4, 990/s. > > But 5.8, and recent Cog/Stack VMs only do < 500 wakeups/sec. Both Carbon and Cocoa versions. > > - Bert - > idle process / relinquish primitive. I turned Matthew's snippet into the attached test. Another strange thing is that (on a recent Mac VM) this test fails for 1mS and 5 mS, but passes for 2mS! HTH. Cheers, Juan Vuletich 'From Cuis 3.3 of 2 June 2011 [latest update: #1024] on 15 July 2011 at 8:28:03 am'! !classDefinition: #RelinquishPrimitiveTest category: #'Kernel-Tests'! TestCase subclass: #RelinquishPrimitiveTest instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Kernel-Tests'! !RelinquishPrimitiveTest methodsFor: 'testing' stamp: 'jmv 7/15/2011 08:25'! testDelayAccuracy " RelinquishPrimitiveTest new testDelayAccuracy Test void relinquishPhysicalProcessor(void); in the VM. See http://bugs.squeak.org/view.php?id=7652 See http://permalink.gmane.org/gmane.comp.lang.smalltalk.squeak.vm.devel/6381 It appears that for some VMs, the relinquish primitiva takes too long to return? This should print a number close to 1000 | tally delay morph updateDelay | tally := 0. delay := Delay forMilliseconds: 1. updateDelay := Delay forMilliseconds: 1000. morph := StringMorph new openInWorld. [[tally := tally + 1. delay wait] repeat] forkAt: 44. [[morph contents: tally printString. tally := 0. updateDelay wait] repeat] forkAt: 45. Evaluating this avoids the iddle process, and in some VMs (Linux) it seems to make the tally go from almost 500 to almost 1000. This trick doesn't seem to work on recent Mac VMs (the 4.2.4 Mac VM is always close 1000), as it is always a bit below 500 [[] repeat] forkAt: 35 " self testDelayAccuracy: 10. self testDelayAccuracy: 6. self testDelayAccuracy: 5. self testDelayAccuracy: 2. self testDelayAccuracy: 1! ! !RelinquishPrimitiveTest methodsFor: 'testing' stamp: 'jmv 7/15/2011 08:27'! testDelayAccuracy: delayTime " RelinquishPrimitiveTest new testDelayAccuracy See comment there. " | tally delay updateDelay counter | tally _ 0. delay _ Delay forMilliseconds: delayTime. updateDelay _ Delay forMilliseconds: 1000. counter _ [[tally _ tally + 1. delay wait] repeat] newProcess. counter resumeAt: 44. tally _ 0. updateDelay wait. counter terminate. self assert: tally > (900/delayTime) description: 'Delay accuracy. Observed: ', (1000.0 / tally roundTo: 0.01) printString, ' mS. Requested: ', delayTime asFloat printString, ' mS.'! ! |
I'll see if can gather some historical thoughts on this later today Sent from my iPhone On 2011-07-15, at 7:47 AM, Juan Vuletich <[hidden email]> wrote: > > Bert Freudenberg wrote: >> On 15.07.2011, at 01:40, Matthew Fulmer wrote: >> >> >>> On my unix vm, Delay wakeups often happen a lot later than requested >>> if the idle process kicks in. Craig provided a bit of code from spoon >>> that fixes this issue: >>> http://bugs.squeak.org/view.php?id=7652 >>> >> >> Very interesting. >> >> On John's 4.x Mac VM I get 990 wakeups/sec. >> >> Same for John's 5.7.4, 990/s. >> >> But 5.8, and recent Cog/Stack VMs only do < 500 wakeups/sec. Both Carbon and Cocoa versions. >> >> - Bert - >> > > Right. Strangely, on recent Mac VMs, the behavior is not affected by idle process / relinquish primitive. I turned Matthew's snippet into the attached test. Another strange thing is that (on a recent Mac VM) this test fails for 1mS and 5 mS, but passes for 2mS! > > HTH. > > Cheers, > Juan Vuletich > 'From Cuis 3.3 of 2 June 2011 [latest update: #1024] on 15 July 2011 at 8:28:03 am'! > !classDefinition: #RelinquishPrimitiveTest category: #'Kernel-Tests'! > TestCase subclass: #RelinquishPrimitiveTest > instanceVariableNames: '' > classVariableNames: '' > poolDictionaries: '' > category: 'Kernel-Tests'! > > !RelinquishPrimitiveTest methodsFor: 'testing' stamp: 'jmv 7/15/2011 08:25'! > testDelayAccuracy > " > RelinquishPrimitiveTest new testDelayAccuracy > Test void relinquishPhysicalProcessor(void); in the VM. > See http://bugs.squeak.org/view.php?id=7652 > See http://permalink.gmane.org/gmane.comp.lang.smalltalk.squeak.vm.devel/6381 > It appears that for some VMs, the relinquish primitiva takes too long to return? > > This should print a number close to 1000 > | tally delay morph updateDelay | > tally := 0. delay := Delay forMilliseconds: 1. > updateDelay := Delay forMilliseconds: 1000. > morph := StringMorph new openInWorld. > [[tally := tally + 1. delay wait] repeat] forkAt: 44. > [[morph contents: tally printString. tally := 0. updateDelay wait] repeat] forkAt: 45. > > Evaluating this avoids the iddle process, and in some VMs (Linux) it seems to make the tally go from almost 500 to almost 1000. > This trick doesn't seem to work on recent Mac VMs (the 4.2.4 Mac VM is always close 1000), as it is always a bit below 500 > [[] repeat] forkAt: 35 > " > self testDelayAccuracy: 10. > self testDelayAccuracy: 6. > self testDelayAccuracy: 5. > self testDelayAccuracy: 2. > self testDelayAccuracy: 1! ! > > !RelinquishPrimitiveTest methodsFor: 'testing' stamp: 'jmv 7/15/2011 08:27'! > testDelayAccuracy: delayTime > " > RelinquishPrimitiveTest new testDelayAccuracy > See comment there. > " > | tally delay updateDelay counter | > tally _ 0. > delay _ Delay forMilliseconds: delayTime. > updateDelay _ Delay forMilliseconds: 1000. > counter _ [[tally _ tally + 1. delay wait] repeat] newProcess. > counter resumeAt: 44. > tally _ 0. > updateDelay wait. > counter terminate. > self assert: tally > (900/delayTime) description: 'Delay accuracy. Observed: ', > (1000.0 / tally roundTo: 0.01) printString, ' mS. Requested: ', delayTime asFloat printString, ' mS.'! ! |
Ok, so after fiddling with this for the last decade let me had over some words of advice (a) the relinquishPhysicalProcessor (whatever it's called) is passed a value, this value is bogus magic meaningless number (b) I did attempt to get that number from the Delay logic, but mmm good luck, the last attempt killed images because it would deadlock on a mutex semaphore lurking in Delay (c) That led to the realization you could ask for vm->getNextWakeup() tick which might be zero some day. (d) getNextWakeup() might be now() or near now() and sleeping might be a bad idea (e) getNextWakeup() might be now() or in the near past yet we might get called another 8 times before the smalltalk process lurch awake (no idea why that is observed). (f) Anyway you have some reflect of sleep time once you decide how large that value has to be. (g) Isn't it one CPU one process why sleep? (h) The pthread_cond_timedwait (yes I did that years back) won't fly because you miss the interrupt from socket/files/UI which leaves to the odd behavior if squeak is busy good web server, if squeak is idle the bad web server... "it always sends at 50 packets per second " Therefore to sleep you have to use some OS call that let's you sleep but wake up early when work needs to be done. So to help befuddle your operating systems come with a variety of system calls that actually might or might not work. Off then to consider aioSleep() which does this dance with aioPoll () which *cough* has different behaviour if or if there is any file descriptors open. Oddly an iphone app might not have any open for your image lacking changeset and no sockets open... Anyway nanosleep is used as that promises to be more accurate. Then if it terminates early (don't bother checking) we run the aioPoll. If of course nanosleep is defective or non-existant, then we ask aioPoll to do the wait, but that usually has even worse behaviour. Anyway after nanosleep wakes do the dance and service those sockets and file descriptors. On Fri, Jul 15, 2011 at 10:15 AM, John M McIntosh <[hidden email]> wrote: > I'll see if can gather some historical thoughts on this later today > > Sent from my iPhone > > On 2011-07-15, at 7:47 AM, Juan Vuletich <[hidden email]> wrote: > >> >> Bert Freudenberg wrote: >>> On 15.07.2011, at 01:40, Matthew Fulmer wrote: >>> >>> >>>> On my unix vm, Delay wakeups often happen a lot later than requested >>>> if the idle process kicks in. Craig provided a bit of code from spoon >>>> that fixes this issue: >>>> http://bugs.squeak.org/view.php?id=7652 >>>> >>> >>> Very interesting. >>> >>> On John's 4.x Mac VM I get 990 wakeups/sec. >>> >>> Same for John's 5.7.4, 990/s. >>> >>> But 5.8, and recent Cog/Stack VMs only do < 500 wakeups/sec. Both Carbon and Cocoa versions. >>> >>> - Bert - >>> >> >> Right. Strangely, on recent Mac VMs, the behavior is not affected by idle process / relinquish primitive. I turned Matthew's snippet into the attached test. Another strange thing is that (on a recent Mac VM) this test fails for 1mS and 5 mS, but passes for 2mS! >> >> HTH. >> >> Cheers, >> Juan Vuletich >> 'From Cuis 3.3 of 2 June 2011 [latest update: #1024] on 15 July 2011 at 8:28:03 am'! >> !classDefinition: #RelinquishPrimitiveTest category: #'Kernel-Tests'! >> TestCase subclass: #RelinquishPrimitiveTest >> instanceVariableNames: '' >> classVariableNames: '' >> poolDictionaries: '' >> category: 'Kernel-Tests'! >> >> !RelinquishPrimitiveTest methodsFor: 'testing' stamp: 'jmv 7/15/2011 08:25'! >> testDelayAccuracy >> " >> RelinquishPrimitiveTest new testDelayAccuracy >> Test void relinquishPhysicalProcessor(void); in the VM. >> See http://bugs.squeak.org/view.php?id=7652 >> See http://permalink.gmane.org/gmane.comp.lang.smalltalk.squeak.vm.devel/6381 >> It appears that for some VMs, the relinquish primitiva takes too long to return? >> >> This should print a number close to 1000 >> | tally delay morph updateDelay | >> tally := 0. delay := Delay forMilliseconds: 1. >> updateDelay := Delay forMilliseconds: 1000. >> morph := StringMorph new openInWorld. >> [[tally := tally + 1. delay wait] repeat] forkAt: 44. >> [[morph contents: tally printString. tally := 0. updateDelay wait] repeat] forkAt: 45. >> >> Evaluating this avoids the iddle process, and in some VMs (Linux) it seems to make the tally go from almost 500 to almost 1000. >> This trick doesn't seem to work on recent Mac VMs (the 4.2.4 Mac VM is always close 1000), as it is always a bit below 500 >> [[] repeat] forkAt: 35 >> " >> self testDelayAccuracy: 10. >> self testDelayAccuracy: 6. >> self testDelayAccuracy: 5. >> self testDelayAccuracy: 2. >> self testDelayAccuracy: 1! ! >> >> !RelinquishPrimitiveTest methodsFor: 'testing' stamp: 'jmv 7/15/2011 08:27'! >> testDelayAccuracy: delayTime >> " >> RelinquishPrimitiveTest new testDelayAccuracy >> See comment there. >> " >> | tally delay updateDelay counter | >> tally _ 0. >> delay _ Delay forMilliseconds: delayTime. >> updateDelay _ Delay forMilliseconds: 1000. >> counter _ [[tally _ tally + 1. delay wait] repeat] newProcess. >> counter resumeAt: 44. >> tally _ 0. >> updateDelay wait. >> counter terminate. >> self assert: tally > (900/delayTime) description: 'Delay accuracy. Observed: ', >> (1000.0 / tally roundTo: 0.01) printString, ' mS. Requested: ', delayTime asFloat printString, ' mS.'! ! > -- =========================================================================== John M. McIntosh <[hidden email]> Corporate Smalltalk Consulting Ltd. http://www.smalltalkconsulting.com =========================================================================== |
Hi John-- > The pthread_cond_timedwait (yes I did that years back) won't fly > because you miss the interrupt from socket/files/UI which leaves to > the odd behavior if squeak is busy good web server, if squeak is idle > the bad web server... "it always sends at 50 packets per second " In Spoon (the Flow plugin, really), when I signal an external semaphore associated with a socket or whatever when activity happens, I also signal the "activity" mutex that this pthread_cond_timedwait call is waiting on. It works fine; in fact, I had to make this work well, to wake up frequently for socket activity for remote messaging on headless systems. At the time I wrote it, the Unix and Mac VMs remote messaging performance was horrible over this very issue. I also experimented with alternative calls, including select(), and nanosleep(). pthread_cond_timedwait() beat them handily. The aioPoll() stuff just seems like a confusing mess. Also, having this as a named primitive in an external plugin has been very convenient, for enabling this sort of experimentation without having to restart the virtual machine. -C -- Craig Latta www.netjam.org/resume +31 6 2757 7177 + 1 415 287 3547 |
Having ported Flow to OS-9 I can agree on all this. Historical issues were (a) pthread_cond_timedwait was a pthread_cond_timedwait_NP meaning platform specific, maybe that is no longer the case. (b) select() was supported everywhere (c) resistance to change (d) Smalltalk socket implementation has to change (see (c)) (e) Heck I even wrote a translation later for Flow to old socket layer. Maybe in this decade someone can take another run at it given the JIT can way outrun the poor socket implementation. On Sat, Jul 16, 2011 at 5:08 AM, Craig Latta <[hidden email]> wrote: > > > Hi John-- > >> The pthread_cond_timedwait (yes I did that years back) won't fly >> because you miss the interrupt from socket/files/UI which leaves to >> the odd behavior if squeak is busy good web server, if squeak is idle >> the bad web server... "it always sends at 50 packets per second " > > In Spoon (the Flow plugin, really), when I signal an external > semaphore associated with a socket or whatever when activity happens, I > also signal the "activity" mutex that this pthread_cond_timedwait call > is waiting on. It works fine; in fact, I had to make this work well, to > wake up frequently for socket activity for remote messaging on headless > systems. > > At the time I wrote it, the Unix and Mac VMs remote messaging > performance was horrible over this very issue. I also experimented with > alternative calls, including select(), and nanosleep(). > pthread_cond_timedwait() beat them handily. The aioPoll() stuff just > seems like a confusing mess. > > Also, having this as a named primitive in an external plugin has > been very convenient, for enabling this sort of experimentation without > having to restart the virtual machine. > > > -C > > -- > Craig Latta > www.netjam.org/resume > +31 6 2757 7177 > + 1 415 287 3547 > > > -- =========================================================================== John M. McIntosh <[hidden email]> Corporate Smalltalk Consulting Ltd. http://www.smalltalkconsulting.com =========================================================================== |
Hi John,
As the old maintainer of the Mac VM, I wondered if you might know anything about a performance issue I posted to the Seaside forum [1] below. In it I point out that the new Cog'ed Seaside and Pharo releases use 10% CPU at idle on the Mac. 1) http://code.google.com/p/seaside/issues/detail?id=665&colspec=ID%20Type%20Status%20Priority%20Version%20Platform%20Owner%20Summary%20Milestone&start=100. T. Ted Wrinch |
Free forum by Nabble | Edit this page |