diff options
Diffstat (limited to 'base')
-rw-r--r-- | base/compression/lzss_compression.cc | 166 | ||||
-rw-r--r-- | base/compression/lzss_compression.hh | 100 | ||||
-rw-r--r-- | base/compression/null_compression.hh | 72 | ||||
-rw-r--r-- | base/hybrid_pred.cc | 273 | ||||
-rw-r--r-- | base/hybrid_pred.hh | 203 | ||||
-rw-r--r-- | base/loader/aout_object.cc (renamed from base/aout_object.cc) | 0 | ||||
-rw-r--r-- | base/loader/aout_object.hh (renamed from base/aout_object.hh) | 0 | ||||
-rw-r--r-- | base/loader/coff_sym.h (renamed from base/coff_sym.h) | 0 | ||||
-rw-r--r-- | base/loader/coff_symconst.h (renamed from base/coff_symconst.h) | 0 | ||||
-rw-r--r-- | base/loader/ecoff_object.cc (renamed from base/ecoff_object.cc) | 0 | ||||
-rw-r--r-- | base/loader/ecoff_object.hh (renamed from base/ecoff_object.hh) | 0 | ||||
-rw-r--r-- | base/loader/elf_object.cc (renamed from base/elf_object.cc) | 0 | ||||
-rw-r--r-- | base/loader/elf_object.hh (renamed from base/elf_object.hh) | 0 | ||||
-rw-r--r-- | base/loader/exec_aout.h (renamed from base/exec_aout.h) | 0 | ||||
-rw-r--r-- | base/loader/exec_ecoff.h (renamed from base/exec_ecoff.h) | 0 | ||||
-rw-r--r-- | base/loader/object_file.cc (renamed from base/object_file.cc) | 0 | ||||
-rw-r--r-- | base/loader/object_file.hh (renamed from base/object_file.hh) | 0 | ||||
-rw-r--r-- | base/loader/symtab.cc (renamed from base/symtab.cc) | 0 | ||||
-rw-r--r-- | base/loader/symtab.hh (renamed from base/symtab.hh) | 0 | ||||
-rw-r--r-- | base/predictor.hh | 62 | ||||
-rw-r--r-- | base/sat_counter.cc | 269 | ||||
-rw-r--r-- | base/sat_counter.hh | 192 |
22 files changed, 1337 insertions, 0 deletions
diff --git a/base/compression/lzss_compression.cc b/base/compression/lzss_compression.cc new file mode 100644 index 000000000..a1933215a --- /dev/null +++ b/base/compression/lzss_compression.cc @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2003 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** @file + * LZSSCompression definitions. + */ + +#include <assert.h> + +#include "lzss_compression.hh" + +#include "misc.hh" //for fatal + +int +LZSSCompression::findSubString(uint8_t *src, int front, int back, int size) +{ + int subSize = 0; + int max_length = 2048; + if (size - back < max_length) { + max_length = size - back; + } + for (int i = 0; i < max_length; ++i) { + if (src[front+i] != src[back+i]) { + return subSize; + } + ++subSize; + } + return subSize; +} + +int +LZSSCompression::emitByte(uint8_t *dest, uint8_t byte) +{ + if ((byte >> 5 & 0x7) == 0 || (byte >> 5 & 0x7) == 7) { + // If the top 3 bits are the same, emit 00<6bits> + dest[0] = byte & 0x3f; + return 1; + } else { + // emit 01XXXXXX <8 bits> + dest[0] = 0x40; + dest[1] = byte; + return 2; + } +} + +void +LZSSCompression::emitString(uint8_t *dest, uint16_t P, uint16_t L) +{ + // Emit 1<7P> <5P><3L> <8L> + dest[0] = 1<<7 | (P >> 5 & 0x7f); + dest[1] = ((P & 0x1f) << 3) | (L>>8 & 0x3); + dest[2] = L & 0xFF; +} + +int +LZSSCompression::compress(uint8_t *dest, uint8_t *src, int size) +{ + if (size > 4096) { + fatal("Compression can only handle block sizes of 4096 bytes or less"); + } + + // Encode the first byte. + int dest_index = emitByte(dest, src[0]); + int i = 1; + // A 11 bit field + uint16_t L; + // A 12 bit field + uint16_t P = 0; + + while (i < size && dest_index < size) { + L = 0; + + if (dest_index+3 >= size) { + dest_index = size; + continue; + } + + if (i == size - 1) { + // Output the character + dest_index += emitByte(&dest[dest_index], src[i]); + ++i; + continue; + } + for (int j = 0; j < i; ++j) { + int sub_size = findSubString(src, j, i, size); + if (sub_size >= L) { + L = sub_size; + P = j; + } + } + if (L > 1) { + // Output the string reference + emitString(&dest[dest_index], P, L); + dest_index += 3; + i = i+L; + } else { + // Output the character + dest_index += emitByte(&dest[dest_index], src[i]); + ++i; + } + } + + if (dest_index >= size) { + // Have expansion instead of compression, just copy. + memcpy(dest,src,size); + return size; + } + return dest_index; +} + +int +LZSSCompression::uncompress(uint8_t *dest, uint8_t *src, int size) +{ + int index = 0; + int i = 0; + while (i < size) { + if (src[i] & 1<<7 ) { + // We have a string + // Extract P + int start = (src[i] & 0x3f)<<5 | ((src[i+1] >> 3) & 0x1f); + // Extract L + int len = (src[i+1] & 0x07)<<8 | src[i+2]; + i += 3; + for (int j = start; j < start+len; ++j) { + dest[index++] = dest[j]; + } + } else { + // We have a character + if (src[i] & 1<<6) { + // Value is in the next byte + dest[index++] = src[i+1]; + i += 2; + } else { + // just extend the lower 6 bits + dest[index++] = (src[i] & 0x3f) | ((src[i] & 1<<5) ? 0xC0 : 0); + ++i; + } + } + } + return index; +} diff --git a/base/compression/lzss_compression.hh b/base/compression/lzss_compression.hh new file mode 100644 index 000000000..5fb47d3f1 --- /dev/null +++ b/base/compression/lzss_compression.hh @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2003 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __LZSS_COMPRESSION_HH__ +#define __LZSS_COMPRESSION_HH__ + +/** @file + * LZSSCompression declarations. + */ + +#include "host.hh" // for uint8_t + +/** + * Simple LZSS compression scheme. + */ +class LZSSCompression +{ + /** + * Finds the longest substrings that start at the given offsets. + * @param src The source block that we search for substrings. + * @param front The smaller offset. + * @param back The larger offset. + * @param size The size of the source block. + * @return The size of the longest substring. + */ + int findSubString(uint8_t *src, int front, int back, int size); + + /** + * Emit an encoded byte to the compressed data array. If the 2 high + * order bits can be signed extended, use 1 byte encoding, if not use 2 + * bytes. + * @param dest The compressed data. + * @param byte The byte to emit. + * @return The number of bytes used to encode. + */ + int emitByte(uint8_t *dest, uint8_t byte); + + /** + * Emit a string reference to the compressed data array. A string reference + * always uses 3 bytes. 1 flag bit, 12 bits for the starting position, and + * 11 bits for the length of the string. This allows compression of 4096 + * byte blocks with string lengths of up to 2048 bytes. + * @param dest The compressed data. + * @param P The starting position in the uncompressed data. + * @param L The length in bytes of the string. + */ + void emitString(uint8_t *dest, uint16_t P, uint16_t L); + + public: + /** + * Compresses the source block and stores it in the destination block. If + * the compressed block grows to larger than the source block, it aborts + * and just performs a copy. + * @param dest The destination block. + * @param src The block to be compressed. + * @param size The size of the source block. + * @return The size of the compressed block. + * + * @pre Destination has enough storage to hold the compressed block. + */ + int compress(uint8_t *dest, uint8_t *src, int size); + + /** + * Unompresses the source block and stores it in the destination block. + * @param dest The destination block. + * @param src The block to be uncompressed. + * @param size The size of the source block. + * @return The size of the uncompressed block. + * + * @pre Destination has enough storage to hold the uncompressed block. + */ + int uncompress(uint8_t *dest, uint8_t *src, int size); +}; + +#endif //__LZSS_COMPRESSION_HH__ diff --git a/base/compression/null_compression.hh b/base/compression/null_compression.hh new file mode 100644 index 000000000..d2bc76eef --- /dev/null +++ b/base/compression/null_compression.hh @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2003 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __NULL_COMPRESSION_HH__ +#define __NULL_COMPRESSION_HH__ + +/** + * @file + * This file defines a doNothing compression algorithm. + */ + +/** + * A dummy compression class to use when no data compression is desired. + */ +class NullCompression +{ + public: + /** + * Uncompress the data, causes a fatal since no data should be compressed. + * @param dest The output buffer. + * @param src The compressed data. + * @param size The number of bytes in src. + * + * @retval The size of the uncompressed data. + */ + static int uncompress(uint8_t * dest, uint8_t *src, int size) + { + fatal("Can't uncompress data"); + } + + /** + * Compress the data, just returns the source data. + * @param dest The output buffer. + * @param src The data to be compressed. + * @param size The number of bytes in src. + * + * @retval The size of the compressed data. + */ + + static int compress(uint8_t *dest, uint8_t *src, int size) + { + memcpy(dest,src,size); + return size; + } +}; + +#endif //__NULL_COMPRESSION_HH__ diff --git a/base/hybrid_pred.cc b/base/hybrid_pred.cc new file mode 100644 index 000000000..ed7f781b2 --- /dev/null +++ b/base/hybrid_pred.cc @@ -0,0 +1,273 @@ +/* + * Copyright (c) 2003 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <string> +#include <sstream> + +#include "hybrid_pred.hh" +#include "statistics.hh" +#include "sim_stats.hh" + +using namespace std; + +HybridPredictor::HybridPredictor(const char *_p_name, const char *_z_name, + const char *_o_name, + unsigned _index_bits, unsigned _counter_bits, + unsigned _zero_change, unsigned _one_change, + unsigned _thresh, + unsigned _global_bits, + unsigned _global_thresh, + bool _reg_individual_stats) +{ + stringstream local_name, global_name; + + pred_name = _p_name; + one_name = _o_name; + zero_name = _z_name; + reg_individual_stats = _reg_individual_stats; + + local_name << pred_name.c_str() << ":L"; + local = new SaturatingCounterPred(local_name.str(), zero_name, one_name, + _index_bits, _counter_bits, + _zero_change, _one_change, _thresh); + + global_name << pred_name.c_str() << ":G"; + global = new SaturatingCounterPred(global_name.str(), zero_name, one_name, + 0, _global_bits, 1, 1, _global_thresh); +} + +void HybridPredictor::regStats() +{ + using namespace Statistics; + + string p_name; + stringstream description; + + if (reg_individual_stats) + p_name = pred_name + ":A"; + else + p_name = pred_name; + + + // + // Number of predictions + // + stringstream num_zero_preds; + num_zero_preds << p_name << ":" << zero_name << ":preds"; + description << "number of predictions of " << zero_name; + pred_zero + .name(num_zero_preds.str()) + .desc(description.str()); + description.str(""); + + stringstream num_one_preds; + num_one_preds << p_name << ":" << one_name << ":preds"; + description << "number of predictions of " << one_name; + pred_one + .name(num_one_preds.str()) + .desc(description.str()) + ; + description.str(""); + + // + // Count the number of correct predictions + // + stringstream num_zero_correct; + num_zero_correct << p_name << ":" << zero_name << ":corr_preds"; + description << "number of correct " << zero_name << " preds" ; + correct_pred_zero + .name(num_zero_correct.str()) + .desc(description.str()) + ; + description.str(""); + + stringstream num_one_correct; + num_one_correct << p_name << ":" << one_name << ":corr_preds"; + description << "number of correct " << one_name << " preds" ; + correct_pred_one + .name(num_one_correct.str()) + .desc(description.str()) + ; + description.str(""); + + + // + // Number of predictor updates + // + stringstream num_zero_updates; + num_zero_updates << p_name << ":" << zero_name << ":updates" ; + description << "number of actual " << zero_name << "s" ; + record_zero + .name(num_zero_updates.str()) + .desc(description.str()) + ; + description.str(""); + + stringstream num_one_updates; + num_one_updates << p_name << ":" << one_name << ":updates" ; + description << "number of actual " << one_name << "s" ; + record_one + .name(num_one_updates.str()) + .desc(description.str()) + ; + description.str(""); + + // + // Local & Global predictor stats + // + if (reg_individual_stats) { + local->regStats(); + global->regStats(); + } +} + +void HybridPredictor::regFormulas() +{ + using namespace Statistics; + + string p_name; + stringstream description; + stringstream name; + + if (reg_individual_stats) + p_name = pred_name + ":A"; + else + p_name = pred_name; + + // + // Number of predictions + // + name << p_name << ":predictions" ; + total_preds + .name(name.str()) + .desc("total number of predictions made") + ; + total_preds = pred_one + pred_zero; + name.str(""); + + // + // Fraction of all predictions that are one or zero + // + name << p_name << ":" << zero_name << ":pred_frac"; + description << "fraction of all preds that were " << zero_name ; + frac_preds_zero + .name(name.str()) + .desc(description.str()) + ; + frac_preds_zero = 100 * record_zero / total_preds; + description.str(""); + name.str(""); + + name << p_name << ":" << one_name << ":pred_frac"; + description << "fraction of all preds that were " << one_name ; + frac_preds_one + .name(name.str()) + .desc(description.str()) + ; + frac_preds_one = 100 * record_one / total_preds; + description.str(""); + name.str(""); + + // + // Count the number of correct predictions + // + name << p_name << ":correct_preds" ; + total_correct + .name(name.str()) + .desc("total number of correct predictions made") + ; + total_correct = correct_pred_one + correct_pred_zero; + name.str(""); + + + // + // Prediction accuracy rates + // + name << p_name << ":pred_rate"; + total_accuracy + .name(name.str()) + .desc("fraction of all preds that were correct") + ; + total_accuracy = 100 * total_correct / total_preds; + name.str(""); + + name << p_name << ":" << zero_name << ":pred_rate" ; + description << "fraction of "<< zero_name <<" preds that were correct"; + zero_accuracy + .name(name.str()) + .desc(description.str()) + ; + zero_accuracy = 100 * correct_pred_zero / pred_zero; + description.str(""); + name.str(""); + + name << p_name << ":" << one_name << ":pred_rate" ; + description << "fraction of "<< one_name <<" preds that were correct"; + one_accuracy + .name(name.str()) + .desc(description.str()) + ; + one_accuracy = 100 * correct_pred_one / pred_one; + description.str(""); + name.str(""); + + // + // Coverage + // + name << p_name << ":" << zero_name << ":coverage"; + description << "fraction of " << zero_name + << "s that were predicted correctly"; + zero_coverage + .name(name.str()) + .desc(description.str()) + ; + zero_coverage = 100 * correct_pred_zero / record_zero; + description.str(""); + name.str(""); + + name << p_name << ":" << one_name << ":coverage"; + description << "fraction of " << one_name + << "s that were predicted correctly"; + one_coverage + .name(name.str()) + .desc(description.str()) + ; + one_coverage = 100 * correct_pred_one / record_one; + description.str(""); + name.str(""); + + // + // Local & Global predictor stats + // + if (reg_individual_stats) { + local->regFormulas(); + global->regFormulas(); + } + +} + diff --git a/base/hybrid_pred.hh b/base/hybrid_pred.hh new file mode 100644 index 000000000..f6e14e3e3 --- /dev/null +++ b/base/hybrid_pred.hh @@ -0,0 +1,203 @@ +/* + * Copyright (c) 2003 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +//========================================================================== +// +// This predictor takes the AND of a "local" and a "global" predictor +// in order to determine its prediction. +// +// +// +// + +#ifndef __HYBRID_PRED_HH__ +#define __HYBRID_PRED_HH__ + +#include <string> + +#include "sat_counter.hh" + +#include "statistics.hh" +#include "sim_stats.hh" + +class HybridPredictor : public GenericPredictor +{ + private: + std::string pred_name; + std::string one_name; + std::string zero_name; + bool reg_individual_stats; + + SaturatingCounterPred *local; + SaturatingCounterPred *global; + + unsigned long max_index; + + // + // Stats + // + Statistics::Scalar<> pred_one; //num_one_preds + Statistics::Scalar<> pred_zero; //num_zero_preds + Statistics::Scalar<> correct_pred_one; //num_one_correct + Statistics::Scalar<> correct_pred_zero; //num_zero_correct + Statistics::Scalar<> record_one; //num_one_updates + Statistics::Scalar<> record_zero; //num_zero_updates + + Statistics::Formula total_preds; + Statistics::Formula frac_preds_zero; + Statistics::Formula frac_preds_one; + Statistics::Formula total_correct; + Statistics::Formula total_accuracy; + Statistics::Formula zero_accuracy; + Statistics::Formula one_accuracy; + Statistics::Formula zero_coverage; + Statistics::Formula one_coverage; + + public: + HybridPredictor(const char *_p_name, const char *_z_name, + const char *_o_name, + unsigned _index_bits, unsigned _counter_bits, + unsigned _zero_change, unsigned _one_change, + unsigned _thresh, + unsigned _global_bits, unsigned _global_thresh, + bool _reg_individual_stats = false); + + void clear() { + global->clear(); + local->clear(); + } + + unsigned peek(unsigned long _index) { + unsigned l = local->peek(_index); + unsigned g = global->peek(_index); + + if (l && g) + return 1; + + return 0; + } + + unsigned value(unsigned long _index) { + unsigned l = local->peek(_index); + unsigned g = global->peek(_index); + + l = l & 0xFFFF; + g = g & 0xFFFF; + + return (l << 16) | g; + + } + + unsigned predict(unsigned long _index) { + unsigned l = local->predict(_index); + unsigned g = global->predict(_index); + + if (l && g) { + ++pred_one; + return 1; + } + + ++pred_zero; + return 0; + } + + + // + // This version need only be used if local/global statistics + // will be maintained + // + unsigned predict(unsigned long _index, unsigned &_pdata) { + unsigned l = local->predict(_index); + unsigned g = global->predict(_index); + + // + // bit 0 => local predictor result + // bit 1 => global predictor result + // + _pdata = 0; + if (l) + _pdata |= 1; + if (g) + _pdata |= 2; + if (l && g) { + ++pred_one; + return 1; + } + + ++pred_zero; + return 0; + } + + void record(unsigned long _index, unsigned _val, unsigned _predicted) { + + if (_val) { + local->record(_index, _val, 0); + global->record(_index, _val, 0); + ++record_one; + + if (_val == _predicted) { + ++correct_pred_one; + } + } else { + local->record(_index, _val, 0); + global->record(_index, _val, 0); + ++record_zero; + + if (_val == _predicted) + ++correct_pred_zero; + } + } + + void record(unsigned long _index, unsigned _val, unsigned _predicted, + unsigned _pdata) + { + + local->record(_index, _val, (_pdata & 1)); + global->record(_index, _val, ((_pdata & 2) ? 1 : 0)); + + + if (_val) { + ++record_one; + + if (_val == _predicted) + ++correct_pred_one; + } else { + ++record_zero; + + if (_val == _predicted) + ++correct_pred_zero; + } + } + + void regStats(); + void regFormulas(); +}; + + +#endif // _HYBRID_PRED_HH__ + diff --git a/base/aout_object.cc b/base/loader/aout_object.cc index c0f43a687..c0f43a687 100644 --- a/base/aout_object.cc +++ b/base/loader/aout_object.cc diff --git a/base/aout_object.hh b/base/loader/aout_object.hh index baa8904a8..baa8904a8 100644 --- a/base/aout_object.hh +++ b/base/loader/aout_object.hh diff --git a/base/coff_sym.h b/base/loader/coff_sym.h index dae9d8590..dae9d8590 100644 --- a/base/coff_sym.h +++ b/base/loader/coff_sym.h diff --git a/base/coff_symconst.h b/base/loader/coff_symconst.h index caed413c2..caed413c2 100644 --- a/base/coff_symconst.h +++ b/base/loader/coff_symconst.h diff --git a/base/ecoff_object.cc b/base/loader/ecoff_object.cc index 87ad6fdca..87ad6fdca 100644 --- a/base/ecoff_object.cc +++ b/base/loader/ecoff_object.cc diff --git a/base/ecoff_object.hh b/base/loader/ecoff_object.hh index af757cd0e..af757cd0e 100644 --- a/base/ecoff_object.hh +++ b/base/loader/ecoff_object.hh diff --git a/base/elf_object.cc b/base/loader/elf_object.cc index 97f50e289..97f50e289 100644 --- a/base/elf_object.cc +++ b/base/loader/elf_object.cc diff --git a/base/elf_object.hh b/base/loader/elf_object.hh index c90f6ebd5..c90f6ebd5 100644 --- a/base/elf_object.hh +++ b/base/loader/elf_object.hh diff --git a/base/exec_aout.h b/base/loader/exec_aout.h index baed30c42..baed30c42 100644 --- a/base/exec_aout.h +++ b/base/loader/exec_aout.h diff --git a/base/exec_ecoff.h b/base/loader/exec_ecoff.h index 8c559ab90..8c559ab90 100644 --- a/base/exec_ecoff.h +++ b/base/loader/exec_ecoff.h diff --git a/base/object_file.cc b/base/loader/object_file.cc index 07b10b5ee..07b10b5ee 100644 --- a/base/object_file.cc +++ b/base/loader/object_file.cc diff --git a/base/object_file.hh b/base/loader/object_file.hh index 1e37b7b70..1e37b7b70 100644 --- a/base/object_file.hh +++ b/base/loader/object_file.hh diff --git a/base/symtab.cc b/base/loader/symtab.cc index 7beee182b..7beee182b 100644 --- a/base/symtab.cc +++ b/base/loader/symtab.cc diff --git a/base/symtab.hh b/base/loader/symtab.hh index 073325eba..073325eba 100644 --- a/base/symtab.hh +++ b/base/loader/symtab.hh diff --git a/base/predictor.hh b/base/predictor.hh new file mode 100644 index 000000000..7c446f26c --- /dev/null +++ b/base/predictor.hh @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2003 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// +// Abstract base class for a generic predictor +// +// + +#ifndef __PREDICTOR_HH__ +#define __PREDICTOR_HH__ + +struct stat_sdb_t; + +class GenericPredictor { + + public: + virtual void clear() = 0; + + virtual unsigned predict(unsigned long _index) = 0; + virtual unsigned predict(unsigned long _index, unsigned &pdata) = 0; + + virtual unsigned peek(unsigned long _index) = 0; + + virtual void record(unsigned long _index, unsigned _actual_value, + unsigned _pred_value) = 0; + virtual void record(unsigned long _index, unsigned _actual_value, + unsigned _pred_value, unsigned _pdata) = 0; + + virtual unsigned value(unsigned long _index) = 0; + + virtual void regStats() = 0; + virtual void regFormulas() = 0; + + virtual ~GenericPredictor() {}; +}; + +#endif // __PREDICTOR_HH__ diff --git a/base/sat_counter.cc b/base/sat_counter.cc new file mode 100644 index 000000000..dc365f0f3 --- /dev/null +++ b/base/sat_counter.cc @@ -0,0 +1,269 @@ +/* + * Copyright (c) 2003 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sstream> + +#include "sat_counter.hh" + +#include "statistics.hh" +#include "sim_stats.hh" + + +using namespace std; + + +SaturatingCounterPred::SaturatingCounterPred(string p_name, + string z_name, + string o_name, + unsigned _index_bits, + unsigned _counter_bits, + unsigned _zero_change, + unsigned _one_change, + unsigned _thresh, + unsigned _init_value) +{ + pred_name = p_name; + zero_name = z_name; + one_name = o_name; + + index_bits = _index_bits; + counter_bits = _counter_bits; + zero_change = _zero_change; + one_change = _one_change; + thresh = _thresh; + init_value = _init_value; + + max_index = (1 << index_bits) - 1; + max_value = (1 << counter_bits) - 1; + + table = new unsigned[max_index + 1]; + + // Initialize with the right parameters & clear the counter + for (int i = 0; i <= max_index; ++i) + table[i] = init_value; +} + +void SaturatingCounterPred::regStats() +{ + using namespace Statistics; + stringstream name, description; + + // + // Number of predictions + // + name << pred_name << ":" << zero_name << ":preds"; + description << "number of predictions of " << zero_name; + predicted_zero + .name(name.str()) + .desc(description.str()) + ; + description.str(""); + name.str(""); + + name << pred_name << ":" << one_name << ":preds"; + description << "number of predictions of " << one_name; + predicted_one + .name(name.str()) + .desc(description.str()) + ; + description.str(""); + name.str(""); + + // + // Count the number of correct predictions + // + name << pred_name << ":" << zero_name << ":corr_preds"; + description << "number of correct " << zero_name << " preds"; + correct_pred_zero + .name(name.str()) + .desc(description.str()) + ; + description.str(""); + name.str(""); + + name << pred_name << ":" << one_name << ":corr_preds"; + description << "number of correct " << one_name << " preds"; + correct_pred_one + .name(name.str()) + .desc(description.str()) + ; + description.str(""); + name.str(""); + + // + // Number of predictor updates + // + name << pred_name << ":" << zero_name << ":updates"; + description << "number of actual " << zero_name << "s"; + record_zero + .name(name.str()) + .desc(description.str()) + ; + description.str(""); + name.str(""); + + name << pred_name << ":" << one_name << ":updates"; + description << "number of actual " << one_name << "s"; + record_one + .name(name.str()) + .desc(description.str()) + ; + description.str(""); + name.str(""); +} + +void SaturatingCounterPred::regFormulas() +{ + using namespace Statistics; + stringstream name, description; + + // + // Number of predictions + // + name << pred_name << ":predictions"; + preds_total + .name(name.str()) + .desc("total number of predictions made") + ; + preds_total = predicted_zero + predicted_one; + name.str(""); + + // + // Fraction of all predictions that are one or zero + // + name << pred_name << ":" << zero_name << ":pred_frac"; + description << "fraction of all preds that were " << zero_name; + pred_frac_zero + .name(name.str()) + .desc(description.str()) + ; + pred_frac_zero = 100 * predicted_zero / preds_total; + description.str(""); + name.str(""); + + name << pred_name << ":" << one_name << ":pred_frac"; + description << "fraction of all preds that were " << one_name; + pred_frac_one + .name(name.str()) + .desc(description.str()) + ; + pred_frac_one = 100 * predicted_one / preds_total; + description.str(""); + name.str(""); + + + // + // Count the number of correct predictions + // + name << pred_name << ":correct_preds"; + correct_total + .name(name.str()) + .desc("total correct predictions made") + ; + correct_total = correct_pred_one + correct_pred_zero; + name.str(""); + + // + // Number of predictor updates + // + name << pred_name << ":updates"; + updates_total + .name(name.str()) + .desc("total number of updates") + ; + updates_total = record_zero + record_one; + name.str(""); + + // + // Prediction accuracy rates + // + name << pred_name << ":pred_rate"; + pred_rate + .name(name.str()) + .desc("correct fraction of all preds") + ; + pred_rate = correct_total / updates_total; + name.str(""); + + name << pred_name << ":" << zero_name << ":pred_rate"; + description << "fraction of " << zero_name << " preds that were correct"; + frac_correct_zero + .name(name.str()) + .desc(description.str()) + ; + frac_correct_zero = 100 * correct_pred_zero / + (correct_pred_zero + record_one - correct_pred_one); + description.str(""); + name.str(""); + + name << pred_name << ":" << one_name << ":pred_rate"; + description << "fraction of " << one_name << " preds that were correct"; + frac_correct_one + .name(name.str()) + .desc(description.str()) + ; + frac_correct_one = 100 * correct_pred_one / + (correct_pred_one + record_zero - correct_pred_zero); + description.str(""); + name.str(""); + + // + // Coverage + // + name << pred_name << ":" << zero_name << ":coverage"; + description << "fraction of " << zero_name + << "s that were predicted correctly"; + coverage_zero + .name(name.str()) + .desc(description.str()) + ; + coverage_zero = 100 * correct_pred_zero / record_zero; + description.str(""); + name.str(""); + + name << pred_name << ":" << one_name << ":coverage"; + description << "fraction of " << one_name + << "s that were predicted correctly"; + coverage_one + .name(name.str()) + .desc(description.str()) + ; + coverage_one = 100 * correct_pred_one / record_one; + description.str(""); + name.str(""); +} + + + + + + + + + + diff --git a/base/sat_counter.hh b/base/sat_counter.hh new file mode 100644 index 000000000..18eab3574 --- /dev/null +++ b/base/sat_counter.hh @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2003 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __SAT_COUNTER_HH__ +#define __SAT_COUNTER_HH__ + +#include <string> + +#include "predictor.hh" + +#include "statistics.hh" +#include "sim_stats.hh" + +struct stat_sdb_t; + +// +// +// A simple saturating counter predictor +// +// +class SaturatingCounterPred : public GenericPredictor +{ + private: + std::string pred_name; + std::string zero_name; + std::string one_name; + + unsigned index_bits; + unsigned counter_bits; + unsigned zero_change; + unsigned one_change; + unsigned thresh; + unsigned init_value; + + unsigned max_value; // maximum counter value + + unsigned long max_index; // also the index mask value + unsigned *table; + + // Statistics + Statistics::Scalar<> predicted_one; // Total predictions of one, preds_one + Statistics::Scalar<> predicted_zero; // Total predictions of zero, preds_zero + Statistics::Scalar<> correct_pred_one; // Total correct predictions of one, correct_one + Statistics::Scalar<> correct_pred_zero; // Total correct predictions of zero, correct_zero + + Statistics::Scalar<> record_zero; //updates_zero + Statistics::Scalar<> record_one; //updates_one + + Statistics::Formula preds_total; + Statistics::Formula pred_frac_zero; + Statistics::Formula pred_frac_one; + Statistics::Formula correct_total; + Statistics::Formula updates_total; + Statistics::Formula pred_rate; + Statistics::Formula frac_correct_zero; + Statistics::Formula frac_correct_one; + Statistics::Formula coverage_zero; + Statistics::Formula coverage_one; + + private: + bool pred_one(unsigned &counter) { return counter > thresh; } + bool pred_zero(unsigned &counter) { return counter <= thresh; } + + void update_one(unsigned &counter) { + + if (one_change) + counter += one_change; + else + counter = 0; + + // check for wrap + if (counter > max_value) + counter = max_value; + } + + void update_zero(unsigned &counter) { + if (zero_change) { + // check for wrap + if (counter < zero_change) + counter = 0; + else + counter -= zero_change; + } else + counter = 0; + } + + + public: + + SaturatingCounterPred(std::string p_name, + std::string z_name, std::string o_name, + unsigned _index_bits, unsigned _counter_bits = 2, + unsigned _zero_change = 1, unsigned _one_change = 1, + unsigned _thresh = 1, unsigned _init_value = 0); + + void clear() { + for (int i = 0; i <= max_index; ++i) + table[i] = init_value; + } + + // Record the ACTUAL result... and indicate whether the prediction + // corresponding to this event was correct + void record(unsigned long _index, unsigned _val, unsigned _predicted, + unsigned _pdata) + { + record(_index, _val, _predicted); + } + + void record(unsigned long _index, unsigned _val, unsigned _predicted) { + unsigned long index = _index & max_index; + + if (_val) { + update_one(table[index]); + ++record_one; + + if (_predicted) + ++correct_pred_one; + } else { + update_zero(table[index]); + ++record_zero; + + if (!_predicted) + ++correct_pred_zero; + } + } + + unsigned value(unsigned long _index) { + unsigned long index = _index & max_index; + + return table[index]; + } + + + unsigned predict(unsigned long _index, unsigned &pdata) { + return predict(_index); + } + + unsigned predict(unsigned long _index) { + unsigned long index = _index & max_index; + + if (pred_one(table[index])) { + ++predicted_one; + return 1; + } + + ++predicted_zero; + return 0; + } + + // No internal state is changed here + unsigned peek(unsigned long _index) { + unsigned long index = _index & max_index; + + if (pred_one(table[index])) + return 1; + + return 0; + } + + + //======================================================= + void regStats(); + void regFormulas(); +}; + + +#endif // __SAT_COUNTER_HH__ |