src/share/vm/utilities/numberSeq.cpp

Thu, 20 Nov 2008 16:56:09 -0800

author
ysr
date
Thu, 20 Nov 2008 16:56:09 -0800
changeset 888
c96030fff130
parent 777
37f87013dfd8
child 1521
89f1b9ae8991
permissions
-rw-r--r--

6684579: SoftReference processing can be made more efficient
Summary: For current soft-ref clearing policies, we can decide at marking time if a soft-reference will definitely not be cleared, postponing the decision of whether it will definitely be cleared to the final reference processing phase. This can be especially beneficial in the case of concurrent collectors where the marking is usually concurrent but reference processing is usually not.
Reviewed-by: jmasa

     1 /*
     2  * Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     8  *
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    12  * version 2 for more details (a copy is included in the LICENSE file that
    13  * accompanied this code).
    14  *
    15  * You should have received a copy of the GNU General Public License version
    16  * 2 along with this work; if not, write to the Free Software Foundation,
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    18  *
    19  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    20  * CA 95054 USA or visit www.sun.com if you need additional information or
    21  * have any questions.
    22  *
    23  */
    25 # include "incls/_precompiled.incl"
    26 # include "incls/_numberSeq.cpp.incl"
    28 AbsSeq::AbsSeq(double alpha) :
    29   _num(0), _sum(0.0), _sum_of_squares(0.0),
    30   _davg(0.0), _dvariance(0.0), _alpha(alpha) {
    31 }
    33 void AbsSeq::add(double val) {
    34   if (_num == 0) {
    35     // if the sequence is empty, the davg is the same as the value
    36     _davg = val;
    37     // and the variance is 0
    38     _dvariance = 0.0;
    39   } else {
    40     // otherwise, calculate both
    41     _davg = (1.0 - _alpha) * val + _alpha * _davg;
    42     double diff = val - _davg;
    43     _dvariance = (1.0 - _alpha) * diff * diff + _alpha * _dvariance;
    44   }
    45 }
    47 double AbsSeq::avg() const {
    48   if (_num == 0)
    49     return 0.0;
    50   else
    51     return _sum / total();
    52 }
    54 double AbsSeq::variance() const {
    55   if (_num <= 1)
    56     return 0.0;
    58   double x_bar = avg();
    59   double result = _sum_of_squares / total() - x_bar * x_bar;
    60   if (result < 0.0) {
    61     // due to loss-of-precision errors, the variance might be negative
    62     // by a small bit
    64     //    guarantee(-0.1 < result && result < 0.0,
    65     //        "if variance is negative, it should be very small");
    66     result = 0.0;
    67   }
    68   return result;
    69 }
    71 double AbsSeq::sd() const {
    72   double var = variance();
    73   guarantee( var >= 0.0, "variance should not be negative" );
    74   return sqrt(var);
    75 }
    77 double AbsSeq::davg() const {
    78   return _davg;
    79 }
    81 double AbsSeq::dvariance() const {
    82   if (_num <= 1)
    83     return 0.0;
    85   double result = _dvariance;
    86   if (result < 0.0) {
    87     // due to loss-of-precision errors, the variance might be negative
    88     // by a small bit
    90     guarantee(-0.1 < result && result < 0.0,
    91                "if variance is negative, it should be very small");
    92     result = 0.0;
    93   }
    94   return result;
    95 }
    97 double AbsSeq::dsd() const {
    98   double var = dvariance();
    99   guarantee( var >= 0.0, "variance should not be negative" );
   100   return sqrt(var);
   101 }
   103 NumberSeq::NumberSeq(double alpha) :
   104   AbsSeq(alpha), _maximum(0.0), _last(0.0) {
   105 }
   107 bool NumberSeq::check_nums(NumberSeq *total, int n, NumberSeq **parts) {
   108   for (int i = 0; i < n; ++i) {
   109     if (parts[i] != NULL && total->num() != parts[i]->num())
   110       return false;
   111   }
   112   return true;
   113 }
   115 NumberSeq::NumberSeq(NumberSeq *total, int n, NumberSeq **parts) {
   116   guarantee(check_nums(total, n, parts), "all seq lengths should match");
   117   double sum = total->sum();
   118   for (int i = 0; i < n; ++i) {
   119     if (parts[i] != NULL)
   120       sum -= parts[i]->sum();
   121   }
   123   _num = total->num();
   124   _sum = sum;
   126   // we do not calculate these...
   127   _sum_of_squares = -1.0;
   128   _maximum = -1.0;
   129   _davg = -1.0;
   130   _dvariance = -1.0;
   131 }
   133 void NumberSeq::add(double val) {
   134   AbsSeq::add(val);
   136   _last = val;
   137   if (_num == 0) {
   138     _maximum = val;
   139   } else {
   140     if (val > _maximum)
   141       _maximum = val;
   142   }
   143   _sum += val;
   144   _sum_of_squares += val * val;
   145   ++_num;
   146 }
   149 TruncatedSeq::TruncatedSeq(int length, double alpha):
   150   AbsSeq(alpha), _length(length), _next(0) {
   151   _sequence = NEW_C_HEAP_ARRAY(double, _length);
   152   for (int i = 0; i < _length; ++i)
   153     _sequence[i] = 0.0;
   154 }
   156 void TruncatedSeq::add(double val) {
   157   AbsSeq::add(val);
   159   // get the oldest value in the sequence...
   160   double old_val = _sequence[_next];
   161   // ...remove it from the sum and sum of squares
   162   _sum -= old_val;
   163   _sum_of_squares -= old_val * old_val;
   165   // ...and update them with the new value
   166   _sum += val;
   167   _sum_of_squares += val * val;
   169   // now replace the old value with the new one
   170   _sequence[_next] = val;
   171   _next = (_next + 1) % _length;
   173   // only increase it if the buffer is not full
   174   if (_num < _length)
   175     ++_num;
   177   guarantee( variance() > -1.0, "variance should be >= 0" );
   178 }
   180 // can't easily keep track of this incrementally...
   181 double TruncatedSeq::maximum() const {
   182   if (_num == 0)
   183     return 0.0;
   184   double ret = _sequence[0];
   185   for (int i = 1; i < _num; ++i) {
   186     double val = _sequence[i];
   187     if (val > ret)
   188       ret = val;
   189   }
   190   return ret;
   191 }
   193 double TruncatedSeq::last() const {
   194   if (_num == 0)
   195     return 0.0;
   196   unsigned last_index = (_next + _length - 1) % _length;
   197   return _sequence[last_index];
   198 }
   200 double TruncatedSeq::oldest() const {
   201   if (_num == 0)
   202     return 0.0;
   203   else if (_num < _length)
   204     // index 0 always oldest value until the array is full
   205     return _sequence[0];
   206   else {
   207     // since the array is full, _next is over the oldest value
   208     return _sequence[_next];
   209   }
   210 }
   212 double TruncatedSeq::predict_next() const {
   213   if (_num == 0)
   214     return 0.0;
   216   double num           = (double) _num;
   217   double x_squared_sum = 0.0;
   218   double x_sum         = 0.0;
   219   double y_sum         = 0.0;
   220   double xy_sum        = 0.0;
   221   double x_avg         = 0.0;
   222   double y_avg         = 0.0;
   224   int first = (_next + _length - _num) % _length;
   225   for (int i = 0; i < _num; ++i) {
   226     double x = (double) i;
   227     double y =  _sequence[(first + i) % _length];
   229     x_squared_sum += x * x;
   230     x_sum         += x;
   231     y_sum         += y;
   232     xy_sum        += x * y;
   233   }
   234   x_avg = x_sum / num;
   235   y_avg = y_sum / num;
   237   double Sxx = x_squared_sum - x_sum * x_sum / num;
   238   double Sxy = xy_sum - x_sum * y_sum / num;
   239   double b1 = Sxy / Sxx;
   240   double b0 = y_avg - b1 * x_avg;
   242   return b0 + b1 * num;
   243 }

mercurial