Prefetcher.hh revision 9466:23e13ad7091f
1/* 2 * Copyright (c) 1999-2012 Mark D. Hill and David A. Wood 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; 9 * redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution; 12 * neither the name of the copyright holders nor the names of its 13 * contributors may be used to endorse or promote products derived from 14 * this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29#ifndef PREFETCHER_H 30#define PREFETCHER_H 31 32// Implements Power 4 like prefetching 33 34#include <bitset> 35 36#include "base/statistics.hh" 37#include "mem/ruby/buffers/MessageBuffer.hh" 38#include "mem/ruby/common/Address.hh" 39#include "mem/ruby/slicc_interface/AbstractController.hh" 40#include "mem/ruby/slicc_interface/RubyRequest.hh" 41#include "mem/ruby/system/System.hh" 42#include "params/Prefetcher.hh" 43#include "sim/sim_object.hh" 44 45#define MAX_PF_INFLIGHT 8 46 47class PrefetchEntry 48{ 49 public: 50 /// constructor 51 PrefetchEntry() 52 { 53 // default: 1 cache-line stride 54 m_stride = (1 << RubySystem::getBlockSizeBits()); 55 m_use_time = Cycles(0); 56 m_is_valid = false; 57 } 58 59 //! The base address for the stream prefetch 60 Address m_address; 61 62 //! stride distance to get next address from 63 int m_stride; 64 65 //! the last time that any prefetched request was used 66 Cycles m_use_time; 67 68 //! valid bit for each stream 69 bool m_is_valid; 70 71 //! L1D prefetches loads and stores 72 RubyRequestType m_type; 73 74 //! Bitset for tracking prefetches for which addresses have been 75 //! issued, which ones have completed. 76 std::bitset<MAX_PF_INFLIGHT> requestIssued; 77 std::bitset<MAX_PF_INFLIGHT> requestCompleted; 78}; 79 80class Prefetcher : public SimObject 81{ 82 public: 83 typedef PrefetcherParams Params; 84 Prefetcher(const Params *p); 85 ~Prefetcher(); 86 87 void issueNextPrefetch(const Address &address, PrefetchEntry *stream); 88 /** 89 * Implement the prefetch hit(miss) callback interface. 90 * These functions are called by the cache when it hits(misses) 91 * on a line with the line's prefetch bit set. If this address 92 * hits in m_array we will continue prefetching the stream. 93 */ 94 void observePfHit(const Address& address); 95 void observePfMiss(const Address& address); 96 97 /** 98 * Observe a memory miss from the cache. 99 * 100 * @param address The physical address that missed out of the cache. 101 */ 102 void observeMiss(const Address& address, const RubyRequestType& type); 103 104 /** 105 * Print out some statistics 106 */ 107 void print(std::ostream& out) const; 108 void setController(AbstractController *_ctrl) 109 { m_controller = _ctrl; } 110 111 void regStats(); 112 113 private: 114 /** 115 * Returns an unused stream buffer (or if all are used, returns the 116 * least recently used (accessed) stream buffer). 117 * @return The index of the least recently used stream buffer. 118 */ 119 uint32_t getLRUindex(void); 120 121 //! clear a non-unit stride prefetcher entry 122 void clearNonunitEntry(uint32_t index); 123 124 //! allocate a new stream buffer at a specific index 125 void initializeStream(const Address& address, int stride, 126 uint32_t index, const RubyRequestType& type); 127 128 //! get pointer to the matching stream entry, returns NULL if not found 129 //! index holds the multiple of the stride this address is. 130 PrefetchEntry* getPrefetchEntry(const Address &address, 131 uint32_t &index); 132 133 /// access a unit stride filter to determine if there is a hit 134 bool accessUnitFilter(std::vector<Address>& filter_table, 135 uint32_t *hit_table, uint32_t &index, const Address &address, 136 int stride, bool &alloc); 137 138 /// access a unit stride filter to determine if there is a hit 139 bool accessNonunitFilter(const Address& address, int *stride, 140 bool &alloc); 141 142 //! number of prefetch streams available 143 uint32_t m_num_streams; 144 //! an array of the active prefetch streams 145 std::vector<PrefetchEntry> m_array; 146 147 //! number of misses I must see before allocating a stream 148 uint32_t m_train_misses; 149 //! number of initial prefetches to startup a stream 150 uint32_t m_num_startup_pfs; 151 //! number of stride filters 152 uint32_t m_num_unit_filters; 153 //! number of non-stride filters 154 uint32_t m_num_nonunit_filters; 155 156 /// a unit stride filter array: helps reduce BW requirement of 157 /// prefetching 158 std::vector<Address> m_unit_filter; 159 /// a round robin pointer into the unit filter group 160 uint32_t m_unit_filter_index; 161 //! An array used to count the of times particular filter entries 162 //! have been hit 163 uint32_t *m_unit_filter_hit; 164 165 //! a negative nit stride filter array: helps reduce BW requirement 166 //! of prefetching 167 std::vector<Address> m_negative_filter; 168 /// a round robin pointer into the negative filter group 169 uint32_t m_negative_filter_index; 170 /// An array used to count the of times particular filter entries 171 /// have been hit 172 uint32_t *m_negative_filter_hit; 173 174 /// a non-unit stride filter array: helps reduce BW requirement of 175 /// prefetching 176 std::vector<Address> m_nonunit_filter; 177 /// An array of strides (in # of cache lines) for the filter entries 178 int *m_nonunit_stride; 179 /// An array used to count the of times particular filter entries 180 /// have been hit 181 uint32_t *m_nonunit_hit; 182 /// a round robin pointer into the unit filter group 183 uint32_t m_nonunit_index; 184 185 /// Used for allowing prefetches across pages. 186 bool m_prefetch_cross_pages; 187 188 AbstractController *m_controller; 189 190 //! Count of accesses to the prefetcher 191 Stats::Scalar numMissObserved; 192 //! Count of prefetch streams allocated 193 Stats::Scalar numAllocatedStreams; 194 //! Count of prefetch requests made 195 Stats::Scalar numPrefetchRequested; 196 //! Count of prefetch requests accepted 197 Stats::Scalar numPrefetchAccepted; 198 //! Count of prefetches dropped 199 Stats::Scalar numDroppedPrefetches; 200 //! Count of successful prefetches 201 Stats::Scalar numHits; 202 //! Count of partial successful prefetches 203 Stats::Scalar numPartialHits; 204 //! Count of pages crossed 205 Stats::Scalar numPagesCrossed; 206 //! Count of misses incurred for blocks that were prefetched 207 Stats::Scalar numMissedPrefetchedBlocks; 208}; 209 210#endif // PREFETCHER_H 211