Stats.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 //==========================================================================
00004 /**
00005  *  @file    Stats.h
00006  *
00007  *  Stats.h,v 4.28 2005/11/07 14:47:07 parsons Exp
00008  *
00009  *  @author David L. Levine
00010  */
00011 //==========================================================================
00012 
00013 
00014 #ifndef ACE_STATS_H
00015 #define ACE_STATS_H
00016 
00017 #include /**/ "ace/pre.h"
00018 
00019 #include "ace/ACE_export.h"
00020 
00021 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00022 # pragma once
00023 #endif /* ACE_LACKS_PRAGMA_ONCE */
00024 
00025 #include "ace/Unbounded_Queue.h"
00026 #include "ace/Log_Msg.h"
00027 #include "ace/Basic_Stats.h"
00028 
00029 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00030 
00031 /**
00032  * @class ACE_Stats_Value
00033  *
00034  * @brief Helper class for ACE_Stats.
00035  *
00036  * Container struct for 64-bit signed quantity and its
00037  * precision.  It would be nicer to use a fixed-point class, but
00038  * this is sufficient.  Users typically don't need to use this
00039  * class directly; see ACE_Stats below.
00040  */
00041 class ACE_Export ACE_Stats_Value
00042 {
00043 public:
00044   /**
00045    * Constructor, which requires precision in terms of number of
00046    * decimal digits.  The more variation in the data, and the greater
00047    * the data values, the smaller the precision must be to avoid
00048    * overflow in the standard deviation calculation.  3 might be a
00049    * good value, or maybe 4.  5 will probably be too large for
00050    * non-trivial data sets.
00051    */
00052   ACE_Stats_Value (const u_int precision);
00053 
00054   /// Accessor for precision.
00055   u_int precision (void) const;
00056 
00057   /// Set the whole_ field.
00058   void whole (const ACE_UINT32);
00059 
00060   /// Accessor for the whole_ field.
00061   ACE_UINT32 whole (void) const;
00062 
00063   /// Set the fractional_ field.
00064   void fractional (const ACE_UINT32);
00065 
00066   /// Accessor for the fractional_ field.
00067   ACE_UINT32 fractional (void) const;
00068 
00069   /// Calculates the maximum value of the fractional portion, given its
00070   /// precision.
00071   ACE_UINT32 fractional_field (void) const;
00072 
00073   /**
00074    * Access the value as an _unsigned_ 64 bit quantity.  It scales the
00075    * value up by {precision} decimal digits, so that no precision will
00076    * be lost.  It assumes that {whole_} is >= 0.
00077    */
00078   void scaled_value (ACE_UINT64 &) const;
00079 
00080   /// Print to stdout.
00081   void dump (void) const;
00082 
00083 private:
00084 
00085   ACE_Stats_Value (void) {}
00086 
00087 private:
00088   /// The integer portion of the value.
00089   ACE_UINT32 whole_;
00090 
00091   /// The fractional portion of the value.
00092   ACE_UINT32 fractional_;
00093 
00094   /**
00095    * The number of decimal digits of precision represented by
00096    * {fractional_}.  Not declared const, so the only way to change it
00097    * is via the assignment operator.
00098    */
00099   u_int precision_;
00100 
00101 };
00102 
00103 /**
00104  * @class ACE_Stats
00105  *
00106  * @brief Provides simple statistical analysis.
00107  *
00108  * Simple statistical analysis package.  Prominent features are:
00109  * -# It does not use any floating point arithmetic.
00110  * -# It handles positive and/or negative sample values.  The
00111  *    sample value type is ACE_INT32.
00112  * -# It uses 64 bit unsigned, but not 64 bit signed, quantities
00113  *    internally.
00114  * -# It checks for overflow of internal state.
00115  * -# It has no static variables of other than built-in types.
00116  *
00117  * Example usage:
00118  *
00119  * @verbatim
00120  * ACE_Stats stats;
00121  * for (u_int i = 0; i < n; ++i)
00122  * {
00123  * const ACE_UINT32 sample = ...;
00124  * stats.sample (sample);
00125  * }
00126  * stats.print_summary (3);
00127  * @endverbatim
00128  */
00129 class ACE_Export ACE_Stats
00130 {
00131 public:
00132   /// Default constructor.
00133   ACE_Stats (void);
00134 
00135   /// Provide a new sample.  Returns 0 on success, -1 if it fails due
00136   /// to running out of memory, or to rolling over of the sample count.
00137   int sample (const ACE_INT32 value);
00138 
00139   /// Access the number of samples provided so far.
00140   ACE_UINT32 samples (void) const;
00141 
00142   /// Value of the minimum sample provided so far.
00143   ACE_INT32 min_value (void) const;
00144 
00145   /// Value of the maximum sample provided so far.
00146   ACE_INT32 max_value (void) const;
00147 
00148   /**
00149    * Access the mean of all samples provided so far.  The fractional
00150    * part is to the specified number of digits.  E.g., 3 fractional
00151    * digits specifies that the fractional part is in thousandths.
00152    */
00153   void mean (ACE_Stats_Value &mean,
00154              const ACE_UINT32 scale_factor = 1);
00155 
00156   /// Access the standard deviation, whole and fractional parts.  See
00157   /// description of {mean} method for argument descriptions.
00158   int std_dev (ACE_Stats_Value &std_dev,
00159                const ACE_UINT32 scale_factor = 1);
00160 
00161   /**
00162    * Print summary statistics.  If scale_factor is not 1, then the
00163    * results are divided by it, i.e., each of the samples is scaled
00164    * down by it.  If internal overflow is reached with the specified
00165    * scale factor, it successively tries to reduce it.  Returns -1 if
00166    * there is overflow even with a 0 scale factor.
00167    */
00168   int print_summary (const u_int precision,
00169                      const ACE_UINT32 scale_factor = 1,
00170                      FILE * = stdout) const;
00171 
00172   /// Initialize internal state.
00173   void reset (void);
00174 
00175   /// Utility division function, for ACE_UINT64 dividend.
00176   static void quotient (const ACE_UINT64 dividend,
00177                         const ACE_UINT32 divisor,
00178                         ACE_Stats_Value &quotient);
00179 
00180   /// Utility division function, for ACE_Stats_Value dividend.
00181   static void quotient (const ACE_Stats_Value &dividend,
00182                         const ACE_UINT32 divisor,
00183                         ACE_Stats_Value &quotient);
00184 
00185   /**
00186    * Sqrt function, which uses an oversimplified version of Newton's
00187    * method.  It's not fast, but it doesn't require floating point
00188    * support.
00189    */
00190   static void square_root (const ACE_UINT64 n,
00191                            ACE_Stats_Value &square_root);
00192 
00193   /// Print summary statistics to stdout.
00194   void dump (void) const;
00195 
00196 protected:
00197   /// Internal indication of whether there has been overflow.  Contains
00198   /// the errno corresponding to the cause of overflow.
00199   u_int overflow_;
00200 
00201   /// Number of samples.
00202   ACE_UINT32 number_of_samples_;
00203 
00204   /// Minimum sample value.
00205   ACE_INT32 min_;
00206 
00207   /// Maximum sample value.
00208   ACE_INT32 max_;
00209 
00210   /// The samples.
00211   ACE_Unbounded_Queue <ACE_INT32> samples_;
00212 };
00213 
00214 // ****************************************************************
00215 
00216 
00217 /// A simple class to make throughput and latency analysis.
00218 /**
00219  *
00220  * Keep the relevant information to perform throughput and latency
00221  * analysis, including:
00222  * -# Minimum, Average and Maximum latency
00223  * -# Jitter for the latency
00224  * -# Linear regression for throughput
00225  * -# Accumulate results from several samples to obtain aggregated
00226  *    results, across several threads or experiments.
00227  *
00228  * @todo The idea behind this class was to use linear regression to
00229  *       determine if the throughput was linear or exhibited jitter.
00230  *       Unfortunately it never worked quite right, so only average
00231  *       throughput is computed.
00232  */
00233 class ACE_Export ACE_Throughput_Stats : public ACE_Basic_Stats
00234 {
00235 public:
00236   /// Constructor
00237   ACE_Throughput_Stats (void);
00238 
00239   /// Store one sample
00240   void sample (ACE_UINT64 throughput, ACE_UINT64 latency);
00241 
00242   /// Update the values to reflect the stats in @a throughput
00243   void accumulate (const ACE_Throughput_Stats &throughput);
00244 
00245   /// Print down the stats
00246   void dump_results (const ACE_TCHAR* msg, ACE_UINT32 scale_factor);
00247 
00248   /// Dump the average throughput stats.
00249   static void dump_throughput (const ACE_TCHAR *msg,
00250                                ACE_UINT32 scale_factor,
00251                                ACE_UINT64 elapsed_time,
00252                                ACE_UINT32 samples_count);
00253 private:
00254   /// The last throughput measurement.
00255   ACE_UINT64 throughput_last_;
00256 
00257 #if 0
00258   /// These are the fields that we should keep to perform linear
00259   /// regression
00260   //@{
00261   ///@}
00262   ACE_UINT64 throughput_sum_x_;
00263   ACE_UINT64 throughput_sum_x2_;
00264   ACE_UINT64 throughput_sum_y_;
00265   ACE_UINT64 throughput_sum_y2_;
00266   ACE_UINT64 throughput_sum_xy_;
00267 #endif /* 0 */
00268 };
00269 
00270 ACE_END_VERSIONED_NAMESPACE_DECL
00271 
00272 #if defined (__ACE_INLINE__)
00273 # include "ace/Stats.inl"
00274 #endif /* __ACE_INLINE__ */
00275 
00276 #include /**/ "ace/post.h"
00277 
00278 #endif /* ! ACE_STATS_H */

Generated on Thu Nov 9 09:42:05 2006 for ACE by doxygen 1.3.6