statistics.hh

来自「M5,一个功能强大的多处理器系统模拟器.很多针对处理器架构,性能的研究都使用它作」· HH 代码 · 共 2,775 行 · 第 1/5 页

HH
2,775
字号
                return false;        return true;    }    bool    check() const    {        return storage != NULL;    }    void    reset()    {        for (int i = 0; i < size(); ++i)            data(i)->reset();    }  public:    VectorBase()        : storage(NULL)    {}    ~VectorBase()    {        if (!storage)            return;        for (int i = 0; i < _size; ++i)            data(i)->~Storage();        delete [] reinterpret_cast<char *>(storage);    }    /**     * Return a reference (ScalarProxy) to the stat at the given index.     * @param index The vector index to access.     * @return A reference of the stat.     */    Proxy    operator[](int index)    {        assert (index >= 0 && index < size());        return Proxy(this, index);    }    void update(StatData *data) {}};template <class Stat>class VectorProxy{  private:    Stat *stat;    int offset;    int len;  private:    mutable VResult vec;    typename Stat::Storage *    data(int index)    {        assert(index < len);        return stat->data(offset + index);    }    const typename Stat::Storage *    data(int index) const    {        assert(index < len);        return const_cast<Stat *>(stat)->data(offset + index);    }  public:    const VResult &    result() const    {        vec.resize(size());        for (int i = 0; i < size(); ++i)            vec[i] = data(i)->result(stat->params);        return vec;    }    Result    total() const    {        Result total = 0;        for (int i = 0; i < size(); ++i)            total += data(i)->result(stat->params);        return total;    }  public:    VectorProxy(Stat *s, int o, int l)        : stat(s), offset(o), len(l)    {    }    VectorProxy(const VectorProxy &sp)        : stat(sp.stat), offset(sp.offset), len(sp.len)    {    }    const VectorProxy &    operator=(const VectorProxy &sp)    {        stat = sp.stat;        offset = sp.offset;        len = sp.len;        return *this;    }    ScalarProxy<Stat> operator[](int index)    {        assert (index >= 0 && index < size());        return ScalarProxy<Stat>(stat, offset + index);    }    size_t size() const { return len; }    /**     * This stat has no state.  Nothing to reset.     */    void reset() { }};template <class Stor>class Vector2dBase : public DataAccess{  public:    typedef Stor Storage;    typedef typename Storage::Params Params;    typedef VectorProxy<Vector2dBase<Storage> > Proxy;    friend class ScalarProxy<Vector2dBase<Storage> >;    friend class VectorProxy<Vector2dBase<Storage> >;  protected:    size_t x;    size_t y;    size_t _size;    Storage *storage;    Params params;  protected:    Storage *data(int index) { return &storage[index]; }    const Storage *data(int index) const { return &storage[index]; }    void    doInit(int _x, int _y)    {        assert(_x > 0 && _y > 0 && "sizes must be positive!");        assert(!storage && "already initialized");        Vector2dData *statdata = dynamic_cast<Vector2dData *>(find());        x = _x;        y = _y;        statdata->x = _x;        statdata->y = _y;        _size = x * y;        char *ptr = new char[_size * sizeof(Storage)];        storage = reinterpret_cast<Storage *>(ptr);        for (int i = 0; i < _size; ++i)            new (&storage[i]) Storage(params);        setInit();    }  public:    Vector2dBase()        : storage(NULL)    {}    ~Vector2dBase()    {        if (!storage)            return;        for (int i = 0; i < _size; ++i)            data(i)->~Storage();        delete [] reinterpret_cast<char *>(storage);    }    void    update(Vector2dData *newdata)    {        int size = this->size();        newdata->cvec.resize(size);        for (int i = 0; i < size; ++i)            newdata->cvec[i] = data(i)->value(params);    }    std::string ysubname(int i) const { return (*this->y_subnames)[i]; }    Proxy    operator[](int index)    {        int offset = index * y;        assert (index >= 0 && offset + index < size());        return Proxy(this, offset, y);    }    size_t    size() const    {        return _size;    }    bool    zero() const    {        return data(0)->zero();#if 0        for (int i = 0; i < size(); ++i)            if (!data(i)->zero())                return false;        return true;#endif    }    /**     * Reset stat value to default     */    void    reset()    {        for (int i = 0; i < size(); ++i)            data(i)->reset();    }    bool    check()    {        return storage != NULL;    }};////////////////////////////////////////////////////////////////////////// Non formula statistics/////////////////////////////////////////////////////////////////////////** * Templatized storage and interface for a distrbution stat. */struct DistStor{  public:    /** The parameters for a distribution stat. */    struct Params    {        /** The minimum value to track. */        Counter min;        /** The maximum value to track. */        Counter max;        /** The number of entries in each bucket. */        Counter bucket_size;        /** The number of buckets. Equal to (max-min)/bucket_size. */        int size;    };    enum { fancy = false };  private:    /** The smallest value sampled. */    Counter min_val;    /** The largest value sampled. */    Counter max_val;    /** The number of values sampled less than min. */    Counter underflow;    /** The number of values sampled more than max. */    Counter overflow;    /** The current sum. */    Counter sum;    /** The sum of squares. */    Counter squares;    /** The number of samples. */    Counter samples;    /** Counter for each bucket. */    VCounter cvec;  public:    DistStor(const Params &params)        : cvec(params.size)    {        reset();    }    /**     * Add a value to the distribution for the given number of times.     * @param val The value to add.     * @param number The number of times to add the value.     * @param params The paramters of the distribution.     */    void sample(Counter val, int number, const Params &params)    {        if (val < params.min)            underflow += number;        else if (val > params.max)            overflow += number;        else {            int index = (int)std::floor((val - params.min) / params.bucket_size);            assert(index < size(params));            cvec[index] += number;        }        if (val < min_val)            min_val = val;        if (val > max_val)            max_val = val;        Counter sample = val * number;        sum += sample;        squares += sample * sample;        samples += number;    }    /**     * Return the number of buckets in this distribution.     * @return the number of buckets.     * @todo Is it faster to return the size from the parameters?     */    size_t size(const Params &) const { return cvec.size(); }    /**     * Returns true if any calls to sample have been made.     * @param params The paramters of the distribution.     * @return True if any values have been sampled.     */    bool zero(const Params &params) const    {        return samples == Counter();    }    void update(DistDataData *data, const Params &params)    {        data->min = params.min;        data->max = params.max;        data->bucket_size = params.bucket_size;        data->size = params.size;        data->min_val = (min_val == INT_MAX) ? 0 : min_val;        data->max_val = (max_val == INT_MIN) ? 0 : max_val;        data->underflow = underflow;        data->overflow = overflow;        data->cvec.resize(params.size);        for (int i = 0; i < params.size; ++i)            data->cvec[i] = cvec[i];        data->sum = sum;        data->squares = squares;        data->samples = samples;    }    /**     * Reset stat value to default     */    void reset()    {        min_val = INT_MAX;        max_val = INT_MIN;        underflow = 0;        overflow = 0;        int size = cvec.size();        for (int i = 0; i < size; ++i)            cvec[i] = Counter();        sum = Counter();        squares = Counter();        samples = Counter();    }};/** * Templatized storage and interface for a distribution that calculates mean * and variance. */struct FancyStor{  public:    /**     * No paramters for this storage.     */    struct Params {};    enum { fancy = true };  private:    /** The current sum. */    Counter sum;    /** The sum of squares. */    Counter squares;    /** The number of samples. */    Counter samples;  public:    /**     * Create and initialize this storage.     */    FancyStor(const Params &)        : sum(Counter()), squares(Counter()), samples(Counter())    { }    /**     * Add a value the given number of times to this running average.     * Update the running sum and sum of squares, increment the number of     * values seen by the given number.     * @param val The value to add.     * @param number The number of times to add the value.     * @param p The parameters of this stat.     */    void sample(Counter val, int number, const Params &p)    {        Counter value = val * number;        sum += value;        squares += value * value;        samples += number;    }    void update(DistDataData *data, const Params &params)    {        data->sum = sum;        data->squares = squares;        data->samples = samples;    }    /**     * Return the number of entries in this stat, 1     * @return 1.     */    size_t size(const Params &) const { return 1; }    /**     * Return true if no samples have been added.     * @return True if no samples have been added.     */    bool zero(const Params &) const { return samples == Counter(); }    /**     * Reset stat value to default     */    void reset()    {        sum = Counter();        squares = Counter();        samples = Counter();    }};/** * Templatized storage for distribution that calculates per tick mean and * variance. */struct AvgFancy{  public:    /** No parameters for this storage. */    struct Params {};    enum { fancy = true };  private:    /** Current total. */    Counter sum;    /** Current sum of squares. */    Counter squares;  public:    /**     * Create and initialize this storage.     */    AvgFancy(const Params &) : sum(Counter()), squares(Counter()) {}    /**     * Add a value to the distribution for the given number of times.     * Update the running sum and sum of squares.     * @param val The value to add.     * @param number The number of times to add the value.     * @param p The paramters of the distribution.     */    void sample(Counter val, int number, const Params &p)    {        Counter value = val * number;        sum += value;        squares += value * value;    }    void update(DistDataData *data, const Params &params)    {        data->sum = sum;        data->squares = squares;        data->samples = curTick;    }    /**     * Return the number of entries, in this case 1.     * @return 1.     */    size_t size(const Params &params) const { return 1; }    /**     * Return true if no samples have been added.     * @return True if the sum is zero.     */    bool zero(const Params &params) const { return sum == Counter(); }    /**     * Reset stat value to default     */    void reset()    {        sum = Counter();        squares = Counter();    }};/** * Implementation of a distribution stat. The type of distribution is * determined by the Storage template. @sa ScalarBase */template <class Stor>class DistBase : public DataAccess{  public:    typedef Stor Storage;    /** Define the params of the storage class. */    typedef typename Storage::Params Params;  protected:    /** The storage for this stat. */    char storage[sizeof(Storage)] __attribute__ ((aligned (8)));    /** The parameters for this stat. */    Params params;  protected:    /**     * Retrieve the storage.     * @return The storage object for this stat.     */    Storage *data()    {        return reinterpret_cast<Storage *>(storage);    }    /**     * Retrieve a const pointer to the storage.     * @return A const pointer to the storage object for this stat.     */    const Storage *    data() const    {        return reinterpret_cast<const Storage *>(storage);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?