CacheRecorder.hh revision 11025
16145SN/A/*
28683SN/A * Copyright (c) 1999-2012 Mark D. Hill and David A. Wood
38683SN/A * Copyright (c) 2010 Advanced Micro Devices, Inc.
46145SN/A * All rights reserved.
56145SN/A *
66145SN/A * Redistribution and use in source and binary forms, with or without
76145SN/A * modification, are permitted provided that the following conditions are
86145SN/A * met: redistributions of source code must retain the above copyright
96145SN/A * notice, this list of conditions and the following disclaimer;
106145SN/A * redistributions in binary form must reproduce the above copyright
116145SN/A * notice, this list of conditions and the following disclaimer in the
126145SN/A * documentation and/or other materials provided with the distribution;
136145SN/A * neither the name of the copyright holders nor the names of its
146145SN/A * contributors may be used to endorse or promote products derived from
156145SN/A * this software without specific prior written permission.
166145SN/A *
176145SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
186145SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
196145SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
206145SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
216145SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
226145SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
236145SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
246145SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
256145SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
266145SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
276145SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
286145SN/A */
296145SN/A
306145SN/A/*
317054SN/A * Recording cache requests made to a ruby cache at certain ruby
327054SN/A * time. Also dump the requests to a gziped file.
336145SN/A */
346145SN/A
357054SN/A#ifndef __MEM_RUBY_RECORDER_CACHERECORDER_HH__
367054SN/A#define __MEM_RUBY_RECORDER_CACHERECORDER_HH__
376145SN/A
387456SN/A#include <vector>
397002SN/A
408683SN/A#include "base/hashmap.hh"
4110302Snilay@cs.wisc.edu#include "base/types.hh"
428165SN/A#include "mem/protocol/RubyRequestType.hh"
438683SN/A#include "mem/ruby/common/Address.hh"
448683SN/A#include "mem/ruby/common/DataBlock.hh"
458683SN/A#include "mem/ruby/common/TypeDefines.hh"
466145SN/A
476890SN/Aclass Sequencer;
486145SN/A
498683SN/A/*!
508683SN/A * Class for recording cache contents. Note that the last element of the
518683SN/A * class is an array of length zero. It is used for creating variable
528683SN/A * length object, so that while writing the data to a file one does not
538683SN/A * need to copy the meta data and the actual data separately.
548683SN/A */
558683SN/Aclass TraceRecord {
568683SN/A  public:
578683SN/A    int m_cntrl_id;
5810302Snilay@cs.wisc.edu    Tick m_time;
5911025Snilay@cs.wisc.edu    Addr m_data_address;
6011025Snilay@cs.wisc.edu    Addr m_pc_address;
618683SN/A    RubyRequestType m_type;
628683SN/A    uint8_t m_data[0];
638683SN/A
648683SN/A    void print(std::ostream& out) const;
658683SN/A};
668683SN/A
677054SN/Aclass CacheRecorder
687054SN/A{
697054SN/A  public:
708683SN/A    CacheRecorder();
718683SN/A    ~CacheRecorder();
726145SN/A
738683SN/A    CacheRecorder(uint8_t* uncompressed_trace,
748683SN/A                  uint64_t uncompressed_trace_size,
7510163SN/A                  std::vector<Sequencer*>& SequencerMap,
7610163SN/A                  uint64_t block_size_bytes);
7711025Snilay@cs.wisc.edu    void addRecord(int cntrl, Addr data_addr, Addr pc_addr,
7811025Snilay@cs.wisc.edu                   RubyRequestType type, Tick time, DataBlock& data);
798683SN/A
808683SN/A    uint64 aggregateRecords(uint8_t** data, uint64 size);
818683SN/A
828683SN/A    /*!
838683SN/A     * Function for flushing the memory contents of the caches to the
848683SN/A     * main memory. It goes through the recorded contents of the caches,
858683SN/A     * and issues flush requests. Except for the first one, a flush request
868683SN/A     * is issued only after the previous one has completed. This currently
878683SN/A     * requires use of MOESI Hammer protocol since only that protocol
888683SN/A     * supports flush requests.
898683SN/A     */
908683SN/A    void enqueueNextFlushRequest();
918683SN/A
928683SN/A    /*!
938683SN/A     * Function for fetching warming up the memory and the caches. It goes
948683SN/A     * through the recorded contents of the caches, as available in the
958683SN/A     * checkpoint and issues fetch requests. Except for the first one, a
968683SN/A     * fetch request is issued only after the previous one has completed.
978683SN/A     * It should be possible to use this with any protocol.
988683SN/A     */
998683SN/A    void enqueueNextFetchRequest();
1006145SN/A
1017054SN/A  private:
1027054SN/A    // Private copy constructor and assignment operator
1037054SN/A    CacheRecorder(const CacheRecorder& obj);
1047054SN/A    CacheRecorder& operator=(const CacheRecorder& obj);
1056145SN/A
1068683SN/A    std::vector<TraceRecord*> m_records;
1078683SN/A    uint8_t* m_uncompressed_trace;
1088683SN/A    uint64_t m_uncompressed_trace_size;
1098683SN/A    std::vector<Sequencer*> m_seq_map;
1108683SN/A    uint64_t m_bytes_read;
1118683SN/A    uint64_t m_records_read;
1128683SN/A    uint64_t m_records_flushed;
11310163SN/A    uint64_t m_block_size_bytes;
1146145SN/A};
1156145SN/A
1168683SN/Ainline bool
1178683SN/AcompareTraceRecords(const TraceRecord* n1, const TraceRecord* n2)
1188683SN/A{
1198683SN/A    return n1->m_time > n2->m_time;
1208683SN/A}
1218683SN/A
1227054SN/Ainline std::ostream&
1238683SN/Aoperator<<(std::ostream& out, const TraceRecord& obj)
1246145SN/A{
1257054SN/A    obj.print(out);
1267054SN/A    out << std::flush;
1277054SN/A    return out;
1286145SN/A}
1296145SN/A
1307054SN/A#endif // __MEM_RUBY_RECORDER_CACHERECORDER_HH__
131