Add systemtap markers to math function slow paths
authorSiddhesh Poyarekar <siddhesh@redhat.com>
Fri, 11 Oct 2013 17:07:53 +0000 (22:37 +0530)
committerSiddhesh Poyarekar <siddhesh@redhat.com>
Fri, 11 Oct 2013 17:07:53 +0000 (22:37 +0530)
Add systemtap probes to various slow paths in libm so that application
developers may use systemtap to find out if their applications are
hitting these slow paths.  We have added probes for pow, exp, log,
tan, atan and atan2.

ChangeLog
manual/probes.texi
sysdeps/ieee754/dbl-64/e_atan2.c
sysdeps/ieee754/dbl-64/e_log.c
sysdeps/ieee754/dbl-64/s_atan.c
sysdeps/ieee754/dbl-64/s_tan.c
sysdeps/ieee754/dbl-64/slowexp.c
sysdeps/ieee754/dbl-64/slowpow.c

index c4a5d84..5090784 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2013-10-11  Siddhesh Poyarekar  <siddhesh@redhat.com>
+           Jeff Law  <law@redhat.com>
+
+       * sysdeps/ieee754/dbl-64/e_atan2.c: Include stap-probe.h.
+       (atan2Mp): Add systemtap probe marker.
+       * sysdeps/ieee754/dbl-64/e_log.c: include stap-probe.h.
+       (__ieee754_log): Add systemtap probe marker.
+       * sysdeps/ieee754/dbl-64/s_atan.c: Include stap-probe.h.
+       (atanMp): Add systemtap probe marker.
+       * sysdeps/ieee754/dbl-64/s_tan.c: Include stap-probe.h.
+       (tanMp): Add systemtap probe marker.
+       * sysdeps/ieee754/dbl-64/slowexp.c: Include stap-probe.h.
+       (__slowexp): Add systemtap probe marker.
+       * sysdeps/ieee754/dbl-64/slowpow.c: Include stap-probe.h.
+       (__slowpow): Add systemtap probe marker.
+       * manual/probes.texi: Document probes.
+
 2013-10-11  Eric Biggers  <ebiggers3@gmail.com>
 
        [BZ #15362]
index 1a45c69..5492bb7 100644 (file)
@@ -16,6 +16,7 @@ arguments.
 
 @menu
 * Memory Allocation Probes::  Probes in the memory allocation subsystem
+* Mathematical Function Probes::  Probes in mathematical functions
 @end menu
 
 @node Memory Allocation Probes
@@ -255,3 +256,100 @@ This probe is triggered when function @code{free} decides to adjust the
 dynamic brk/mmap thresholds.  Argument @var{$arg1} and @var{$arg2} are
 the adjusted mmap and trim thresholds, respectively.
 @end deftp
+
+@node Mathematical Function Probes
+@section Mathematical Function Probes
+
+Some mathematical functions fall back to multiple precision arithmetic for
+some inputs to get last bit precision for their return values.  This multiple
+precision fallback is much slower than the default algorithms and may have a
+significant impact on application performance.  The systemtap probe markers
+described in this section may help you determine if your application calls
+mathematical functions with inputs that may result in multiple-precision
+arithmetic.
+
+Unless explicitly mentioned otherwise, a precision of 1 implies 24 bits of
+precision in the mantissa of the multiple precision number.  Hence, a precision
+level of 32 implies 768 bits of precision in the mantissa.
+
+@deftp Probe slowexp_p6 (double @var{$arg1}, double @var{$arg2})
+This probe is hit when the @code{exp} function is called with an input that
+results in multiple precision computation with precision 6. Argument
+@var{$arg1} is the input value and @var{$arg2} is the computed output.
+@end deftp
+
+@deftp Probe slowexp_p32 (double @var{$arg1}, double @var{$arg2})
+This probe is hit when the @code{exp} function is called with an input that
+results in multiple precision computation with precision 32. Argument
+@var{$arg1} is the input value and @var{$arg2} is the computed output.
+@end deftp
+
+@deftp Probe slowpow_p10 (double @var{$arg1}, double @var{$arg2}, double @var{$arg3}, double @var{$arg4})
+This probe is hit when the @code{pow} function is called with inputs that
+result in multiple precision computation with precision 10. Arguments
+@var{$arg1} and @var{$arg2} are the input values, @code{$arg3} is the value
+computed in the fast phase of the algorithm and @code{$arg4} is the final
+accurate value.
+@end deftp
+
+@deftp Probe slowpow_p32 (double @var{$arg1}, double @var{$arg2}, double @var{$arg3}, double @var{$arg4})
+This probe is hit when the @code{pow} function is called with an input that
+results in multiple precision computation with precision 32. Arguments
+@var{$arg1} and @var{$arg2} are the input values, @code{$arg3} is the value
+computed in the fast phase of the algorithm and @code{$arg4} is the final
+accurate value.
+@end deftp
+
+@deftp Probe slowlog (int @var{$arg1}, double @var{$arg2}, double @var{$arg3})
+This probe is hit when the @code{log} function is called with an input that
+results in multiple precision computation.  Argument @var{$arg1} is the
+precision with which the computation succeeded.  Argument @var{$arg2} is the
+input and @var{$arg3} is the computed output.
+@end deftp
+
+@deftp Probe slowlog_inexact (int @var{$arg1}, double @var{$arg2}, double @var{$arg3})
+This probe is hit when the @code{log} function is called with an input that
+results in multiple precision computation and none of the multiple precision
+computations result in an accurate result.  Argument @var{$arg1} is the maximum
+precision  with which computations were performed.  Argument @var{$arg2} is the
+input and @var{$arg3} is the computed output.
+@end deftp
+
+@deftp Probe slowatan2 (int @var{$arg1}, double @var{$arg2}, double @var{$arg3}, double @var{$arg4})
+This probe is hit when the @code{atan2} function is called with an input that
+results in multiple precision computation.  Argument @var{$arg1} is the
+precision with which computation succeeded.  Arguments @var{$arg2} and
+@var{$arg3} are inputs to the @code{atan2} function and @var{$arg4} is the
+computed result.
+@end deftp
+
+@deftp Probe slowatan2_inexact (int @var{$arg1}, double @var{$arg2}, double @var{$arg3}, double @var{$arg4})
+This probe is hit when the @code{atan} function is called with an input that
+results in multiple precision computation and none of the multiple precision
+computations result in an accurate result.  Argument @var{$arg1} is the maximum
+precision  with which computations were performed.  Arguments @var{$arg2} and
+@var{$arg3} are inputs to the @code{atan2} function and @var{$arg4} is the
+computed result.
+@end deftp
+
+@deftp Probe slowatan (int @var{$arg1}, double @var{$arg2}, double @var{$arg3})
+This probe is hit when the @code{atan} function is called with an input that
+results in multiple precision computation.  Argument @var{$arg1} is the
+precision with which computation succeeded.  Argument @var{$arg2} is the
+input to the @code{atan} function and @var{$arg3} is the computed result.
+@end deftp
+
+@deftp Probe slowatan_inexact (int @var{$arg1}, double @var{$arg2}, double @var{$arg3})
+This probe is hit when the @code{atan} function is called with an input that
+results in multiple precision computation and none of the multiple precision
+computations result in an accurate result.  Argument @var{$arg1} is the maximum
+precision  with which computations were performed.  Argument @var{$arg2} is the
+input to the @code{atan} function and @var{$arg3} is the computed result.
+@end deftp
+
+@deftp Probe slowtan (double @var{$arg1}, double @var{$arg2})
+This probe is hit when the @code{tan} function is called with an input that
+results in multiple precision computation with precision 32.  Argument
+@var{$arg1} is the input to the function and @var{$arg2} is the computed
+result.
+@end deftp
index 4ebe9c0..4075622 100644 (file)
@@ -42,6 +42,7 @@
 #include "uatan.tbl"
 #include "atnat2.h"
 #include <math_private.h>
+#include <stap-probe.h>
 
 #ifndef SECTION
 # define SECTION
@@ -597,7 +598,11 @@ atan2Mp (double x, double y, const int pr[])
       __mp_dbl (&mpz1, &z1, p);
       __mp_dbl (&mpz2, &z2, p);
       if (z1 == z2)
-       return z1;
+       {
+         LIBC_PROBE (slowatan2, 4, &p, &x, &y, &z1);
+         return z1;
+       }
     }
+  LIBC_PROBE (slowatan2_inexact, 4, &p, &x, &y, &z1);
   return z1;                   /*if impossible to do exact computing */
 }
index f9300f9..17ab75a 100644 (file)
@@ -39,6 +39,7 @@
 #include "mpa.h"
 #include "MathLib.h"
 #include <math_private.h>
+#include <stap-probe.h>
 
 #ifndef SECTION
 # define SECTION
@@ -242,8 +243,12 @@ stage_n:
       __mp_dbl (&mpy1, &y1, p);
       __mp_dbl (&mpy2, &y2, p);
       if (y1 == y2)
-       return y1;
+       {
+         LIBC_PROBE (slowlog, 3, &p, &x, &y1);
+         return y1;
+       }
     }
+  LIBC_PROBE (slowlog_inexact, 3, &p, &x, &y1);
   return y1;
 }
 
index 7b6c83f..35ab5c1 100644 (file)
@@ -42,6 +42,7 @@
 #include "uatan.tbl"
 #include "atnat.h"
 #include <math.h>
+#include <stap-probe.h>
 
 void __mpatan (mp_no *, mp_no *, int); /* see definition in mpatan.c */
 static double atanMp (double, const int[]);
@@ -306,8 +307,12 @@ atanMp (double x, const int pr[])
       __mp_dbl (&mpy1, &y1, p);
       __mp_dbl (&mpy2, &y2, p);
       if (y1 == y2)
-       return y1;
+       {
+         LIBC_PROBE (slowatan, 3, &p, &x, &y1);
+         return y1;
+       }
     }
+  LIBC_PROBE (slowatan_inexact, 3, &p, &x, &y1);
   return y1;                   /*if impossible to do exact computing */
 }
 
index 54f863e..cc0dbbb 100644 (file)
@@ -41,6 +41,7 @@
 #include <math.h>
 #include <math_private.h>
 #include <fenv.h>
+#include <stap-probe.h>
 
 #ifndef SECTION
 # define SECTION
@@ -838,6 +839,7 @@ tanMp (double x)
   p = 32;
   __mptan (x, &mpy, p);
   __mp_dbl (&mpy, &y, p);
+  LIBC_PROBE (slowtan, 2, &x, &y);
   return y;
 }
 
index 8f353f6..525224f 100644 (file)
@@ -29,6 +29,8 @@
 /**************************************************************************/
 #include <math_private.h>
 
+#include <stap-probe.h>
+
 #ifndef USE_LONG_DOUBLE_FOR_MP
 # include "mpa.h"
 void __mpexp (mp_no *x, mp_no *y, int p);
@@ -60,13 +62,22 @@ __slowexp (double x)
   __mp_dbl (&mpw, &w, p);
   __mp_dbl (&mpz, &z, p);
   if (w == z)
-    return w;
+    {
+      /* Track how often we get to the slow exp code plus
+        its input/output values.  */
+      LIBC_PROBE (slowexp_p6, 2, &x, &w);
+      return w;
+    }
   else
     {
       p = 32;
       __dbl_mp (x, &mpx, p);
       __mpexp (&mpx, &mpy, p);
       __mp_dbl (&mpy, &res, p);
+
+      /* Track how often we get to the uber-slow exp code plus
+        its input/output values.  */
+      LIBC_PROBE (slowexp_p32, 2, &x, &res);
       return res;
     }
 #else
index a379728..d200c39 100644 (file)
@@ -34,6 +34,8 @@
 #include "mpa.h"
 #include <math_private.h>
 
+#include <stap-probe.h>
+
 #ifndef SECTION
 # define SECTION
 #endif
@@ -97,7 +99,12 @@ __slowpow (double x, double y, double z)
   __sub (&mpp, &eps, &mpr1, p);
   __mp_dbl (&mpr1, &res1, p);
   if (res == res1)
-    return res;
+    {
+      /* Track how often we get to the slow pow code plus
+        its input/output values.  */
+      LIBC_PROBE (slowpow_p10, 4, &x, &y, &z, &res);
+      return res;
+    }
 
   /* If we don't, then we repeat using a higher precision.  768 bits of
      precision ought to be enough for anybody.  */
@@ -109,5 +116,10 @@ __slowpow (double x, double y, double z)
   __mul (&mpy, &mpz, &mpw, p);
   __mpexp (&mpw, &mpp, p);
   __mp_dbl (&mpp, &res, p);
+
+  /* Track how often we get to the uber-slow pow code plus
+     its input/output values.  */
+  LIBC_PROBE (slowpow_p32, 4, &x, &y, &z, &res);
+
   return res;
 }