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

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

mercurial