[squeak-dev] Re: How to profile a server image?

Juan Vuletich juan at jvuletich.org
Tue Mar 3 19:56:31 UTC 2009


Hi Eliot,

Eliot Miranda wrote:
> Hi Juan,
>
> On Tue, Mar 3, 2009 at 5:28 AM, Juan Vuletich <juan at jvuletich.org 
> <mailto:juan at jvuletich.org>> wrote:
>
>     Hi Andreas,
>
>     Andreas Raab wrote:
>
>         ...
>
>         This is tricky with MessageTally. There are several issues to
>         keep in mind, some of which you can fix, some of which you
>         can't. Here we go:
>
>         1) Observing all Processes
>         --------------------------
>         First, MessageTally only observes the block you are running,
>         not the entire system. For example, if you were to profile this:
>
>         done := Semaphore new.
>         worker:= [
>            10 timesRepeat:[World changed; displayWorld].
>            done signal.
>         ] fork.
>         MessageTally spyOn:[done wait].
>
>         This is what you'd get:
>
>         **Tree**
>         100.0% {2367ms} primitives
>
>         **Leaves**
>         100.0% {2367ms} UndefinedObject>>DoIt
>
>         Obviously it's not actually measuring what is going on during
>         the period of time which is a real problem if you are trying
>         to measure server load in general. But it's fixable.
>         ...
>
>     I found all this stuff very interesting and useful. Thanks!
>
>     WRT issue 1), what I'd really like is the tally tree to have
>     several roots, one for each forked process. Otherwise, the process
>     that forks other processes would also have their tallies added to
>     him (which is wrong, as it would appear to be using more time than
>     it really did). Fixing this, MessageTally could give a better
>     insight on cpu usage than #tallyCPUUsageFor:.
>
>     To do this, I'd need to find out for a certain context in the
>     sender chain, on which process it was running. (Then, when
>     building the tally tree, I could know that I need to add a new
>     root.) Do you know how to find out? I spent a couple of hours on
>     this, and it seems it is not possible...
>
>
> When MessageTally runs to collect each tally the process that has been 
> interrupted is the highest priority runnable process in the runnable 
> process lists in ProcessorScheduler.  You could implement it like this:
>
> !ProcessorScheduler methodsFor: 'accessing' stamp: 'eem 3/3/2009 10:41'!
> highestPriorityRunnableProcess
> [quiescentProcessLists reverseDo:
> [:each| each isEmpty ifFalse: [^each first]]] valueUnpreemptively.
> ^nil
>
> "| thisProcess interruptedProcess done |
> thisProcess := Processor activeProcess.
> done := false.
> [(Delay forSeconds: 1) wait.
> interruptedProcess := Processor highestPriorityRunnableProcess.
> done := true] forkAt: Processor userInterruptPriority.
> [done] whileFalse.
> self assert: thisProcess == interruptedProcess"! !
>
> So modify MessageTally (or better still create a subclass called 
> MultiProcessMessageTally) that uses the above to manage a set of 
> tallies for each process found while spying.
>
> HTH
>

What you say sounds similar to what Andreas suggests to make 
MessageTally spy over all processes. The issue I point out is that when 
MessageTally
builds the tree, the sender of a context might be in another process. 
This happens when a context forks a new process, it is still its sender. 
So when building the tally tree, I need to query each context for the 
process running it, and when it is different from the parent's one, I'll 
start a new tally tree.

I made it work, by adding an ivar to Process to hold the firstContext 
(the one that is sent to #forContext:priority:). Then, when building the 
tally tree, for each context, I check if it is the firstContext of some 
process. The problem with this approach is that it adds too much 
overhead to the tally.

I'd really appreciate a better way to do this. I'm sure everybody will 
like the multi-process tally that would result!

Cheers,
Juan Vuletich



More information about the Squeak-dev mailing list