stptracer-20060828 has released.
Li Guanglei
guanglei@cn.ibm.com
Tue Sep 5 02:28:00 GMT 2006
Frank Ch. Eigler wrote:
> Hi -
>
> On Fri, Sep 01, 2006 at 11:47:05AM +0800, Li Guanglei wrote:
>
>> [...] But I have some questions about compiled approach. stap will
>> treat all integer data as 64-bit, but most binary trace integer data
>> items need only 1 or 2 bytes. [...] And will it use a fix length for
>> all string items? Some string trace data items only have a few
>> chars.
>
> The translator could apply obvious policies to this question. If the
> formatting string includes "%1b", it would write just the low-order
> byte of the integer. If the formatting string includes "%64s", this
> would result in a fixed-width substring field. For plain "%s", it
> would be a dynamic-width field, which alone would not be ideal for
> binary format streams.
>
> The idea here is to make this compiled tracing a pure optimization:
> not to change the script input nor data output, but just to produce it
> quicker.
>
Thanks. I see.
>
>> [...] But in some situations I will put the print/trace statement in
>> embedded c codes to avoid the calls to function__dwarf_tvar_get*.
>
> If you don't call those tvar_get functions, how are you safely
> extracting target data?
>
>> One example is the struct scsi_cmnd in scsi trace hooks in LKET. I
>> need to retrieve 10 arguments from this struct. In the embedded c
>> codes they are only 10 assignments while in stap script they will be
>> extended to 10 function calls.
>
> In exchange for those function calls, you're getting safe
> dereferencing of all those values. How much slowdown is
> that worth?
I run a series of tests to figure it out. I use the same single-thread
application named app_getsid with will call getsid() in a loop, the
results are:
<1> without probe
cpu 0: loops=5000000, average=392 ns
<2> probe using LKET(2.stp): log 4 integers
cpu 0: loops=5000000, average=2280 ns
<3> probe using LKET(3.stp): log 4 integers + visit 5 target variables
cpu 0: loops=5000000, average=2445 ns
<4> probe using LKST(4.stp): log 4 integers
cpu 0: loops=5000000, average=1710 ns
<5> probe using LKST(5.stp): log 4 integers + visit 5 target variables
cpu 0: loops=5000000, average=1859 ns
The testing shows that visiting 5 target variables will cost ~150ns,
and LKST is ~570ns faster than LKET if only log 4 integers. I think
the compiled approach should have almost the same speed as <5>, so it
will roughly be at least ~420ns faster than LKET.
But it's not common that the trace handler will visit a number of data
members of a single struct. In most cases it will just visit different
target variables and in such case LKET will also need the same number
of tvar_get functions as the compiled approach does in script level.
Most target variables can be visited safely unless there is a bug in
Kernel. Those target variables that could potentially have invalid
values need explicitly checking before use them, and LKET needs a
piece of c codes to check them. But we can't make sure every one
doesn't miss some checking codes. So considering the benefit of
tvar_get() and its cost, I think it is worth to use tvar_get().
The following is the stp scripts.
2.stp:
function foo()
%{
_lket_trace(1, 1, "%8b%8b%8b%8b", 111,22,333,444);
%}
probe syscall.getsid {
foo()
}
3.stp:
function foo(a:long, b:long, c:long, d:long, e:long)
%{
_lket_trace(1, 1, "%8b%8b%8b%8b", 111,22,333,444);
%}
probe syscall.getsid {
foo($pid, $pid, $pid, $pid, $pid)
}
4.stp:
probe syscall.getsid {
lkst_trace_n (4, 1, 12, 222, 333, 4444)
}
5.stp:
function foo:long(a:long, b:long, c:long, d:long, e:long)
%{
THIS->__retvalue = 0;
%}
probe syscall.getsid {
foo($pid, $pid, $pid, $pid, $pid)
lkst_trace_n (4, 1, 12, 222, 333, 4444)
}
- Guanglei
More information about the Systemtap
mailing list