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

Eliot Miranda eliot.miranda at gmail.com
Tue Mar 3 20:34:13 UTC 2009


On Tue, Mar 3, 2009 at 11:56 AM, Juan Vuletich <juan at jvuletich.org> wrote:

> 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 think I see but I wouldn't put it like that.  Yes, new processes get
resumed in the context of other proesses, but no, the sender is not in
another process.  The bottom context of a process has no sender.  So why
bother at all trying to track down in which process a process was created
and leave that to the user when interpreting the profile?

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.


IMO just throw this away.  You don't absolutely need to know on behalf of
which process a process is running.

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


I believe the VW multi-process profiler doesn't bother identifying the
parent process.  But if it does it can do so by e.g. adding an inst var to
process that refers to the parent process, rather than the context in which
the process was created.  But both recording the context or the parent
process are bad ideas for garbage collection.

I would simply use the process name facility (Process>>name[:] as displayed
by the process browser) to label the various tallies you collect.  If a user
can't work out which process is which by just looking at the the profile ten
they can change their code to use Process>>name: to add names to various
processes and then be able to wrk it out.

just my 2¢

best
E.


>
> Cheers,
> Juan Vuletich
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20090303/54504cba/attachment.htm


More information about the Squeak-dev mailing list