This is the mail archive of the
systemtap@sourceware.org
mailing list for the systemtap project.
Re: proposed perf.counter enhancement
- From: fche at redhat dot com (Frank Ch. Eigler)
- To: Stan Cox <scox at redhat dot com>
- Cc: systemtap at sourceware dot org
- Date: Tue, 23 Oct 2012 16:49:37 -0400
- Subject: Re: proposed perf.counter enhancement
- References: <50859301.6060409@redhat.com>
Hi, Stan -
scox wrote:
> [...]
> // Define a perf counter of type X, config Y, sample_freq 0,
> // and task T. Create a global z[cpu, i] to hold the counters.
> // Does not call _stp_perf_init as perf.type.config does, but calls it
> // later in process.begin
>
> probe perf.type(0).config(0).counter("y")
> {
> }
It would be nice to express per-cpu vs. per-thread counters.
> [...]
> // Define a reading counter probe. Init the probe for the task:
> // _stp_perf_init (spr_perf_probes[n], task);
> // and generate an implicit read into the counter collector "z", ie
> // for (i = 0; i < %{ num_online_cpus() %}; i++) {
> // z[i, z_dims[i]++] = %{ _stp_perf_read(l->l_i) %}
What does the zdims[i]++ part mean? Is it necessary to read the
counter values across all CPUs?
> // generate implicit read as above the term the counter: _stp_perf_del
> probe process("pwd").end.counter("z")
> {
> }
This doesn't make much sense to me. The lifetime of some random
process "pwd" would need to spell out the relevance to some counter.
> // generate implicit read for process.function[.return]
> probe process("pwd").function("main").counter("y").counter("z")
> {
> }
>
> probe process("pwd").function("main").return.counter("y").counter("z")
> {
> }
I'd expect these probes to use the z variable somehow, perhaps to save
the deltas in some other array. Plus, if from probe
perf...counter("z"), the translator understands that z is a special
variable, then perhaps it does not need markup of these counter-user
probes, just the mention of the variables.
> probe process("pwd").function("main").counter("y").counter("z")
> {
> z <<< perf_read("z")
> }
(Recall though that the problem with a tapset function for this is
being invoked from atomic context.)
> probe end ()
> {
> foreach (perf in z)
> printf ("counter[%d] = %d\n", z[perf])
> }
(Wasn't z two-dimensional?)
By contrast, here's how I might imagine a similar scenario looking:
probe perf.type(0).config(0).per_thread("y") { } # y implicit special local
global history
probe process("foobar").function("*").return {
index = tid() # or probefunc()
history[index] <<< y-@entry(y)
}
# let implicit global printing take care of [history] stats printing