[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
|