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 "ient); 00179 00180 /// Utility division function, for ACE_Stats_Value dividend. 00181 static void quotient (const ACE_Stats_Value ÷nd, 00182 const ACE_UINT32 divisor, 00183 ACE_Stats_Value "ient); 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 */