Prefetcher.hh revision 10301:44839e8febbd
17753SWilliam.Wang@arm.com/* 27753SWilliam.Wang@arm.com * Copyright (c) 1999-2012 Mark D. Hill and David A. Wood 37753SWilliam.Wang@arm.com * All rights reserved. 47753SWilliam.Wang@arm.com * 57753SWilliam.Wang@arm.com * Redistribution and use in source and binary forms, with or without 67753SWilliam.Wang@arm.com * modification, are permitted provided that the following conditions are 77753SWilliam.Wang@arm.com * met: redistributions of source code must retain the above copyright 87753SWilliam.Wang@arm.com * notice, this list of conditions and the following disclaimer; 97753SWilliam.Wang@arm.com * redistributions in binary form must reproduce the above copyright 107753SWilliam.Wang@arm.com * notice, this list of conditions and the following disclaimer in the 117753SWilliam.Wang@arm.com * documentation and/or other materials provided with the distribution; 127753SWilliam.Wang@arm.com * neither the name of the copyright holders nor the names of its 137753SWilliam.Wang@arm.com * contributors may be used to endorse or promote products derived from 147753SWilliam.Wang@arm.com * this software without specific prior written permission. 157753SWilliam.Wang@arm.com * 167753SWilliam.Wang@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 177753SWilliam.Wang@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 187753SWilliam.Wang@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 197753SWilliam.Wang@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 207753SWilliam.Wang@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 217753SWilliam.Wang@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 227753SWilliam.Wang@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 237753SWilliam.Wang@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 247753SWilliam.Wang@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 257753SWilliam.Wang@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 267753SWilliam.Wang@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 277753SWilliam.Wang@arm.com */ 287753SWilliam.Wang@arm.com 297753SWilliam.Wang@arm.com#ifndef PREFETCHER_H 307753SWilliam.Wang@arm.com#define PREFETCHER_H 317753SWilliam.Wang@arm.com 327753SWilliam.Wang@arm.com// Implements Power 4 like prefetching 337753SWilliam.Wang@arm.com 347753SWilliam.Wang@arm.com#include <bitset> 357753SWilliam.Wang@arm.com 367753SWilliam.Wang@arm.com#include "base/statistics.hh" 377753SWilliam.Wang@arm.com#include "mem/ruby/common/Address.hh" 387753SWilliam.Wang@arm.com#include "mem/ruby/network/MessageBuffer.hh" 397753SWilliam.Wang@arm.com#include "mem/ruby/slicc_interface/AbstractController.hh" 407753SWilliam.Wang@arm.com#include "mem/ruby/slicc_interface/RubyRequest.hh" 417753SWilliam.Wang@arm.com#include "mem/ruby/system/System.hh" 427753SWilliam.Wang@arm.com#include "params/Prefetcher.hh" 437753SWilliam.Wang@arm.com#include "sim/sim_object.hh" 447753SWilliam.Wang@arm.com 457753SWilliam.Wang@arm.com#define MAX_PF_INFLIGHT 8 467753SWilliam.Wang@arm.com 477753SWilliam.Wang@arm.comclass PrefetchEntry 487753SWilliam.Wang@arm.com{ 497753SWilliam.Wang@arm.com public: 507753SWilliam.Wang@arm.com /// constructor 517753SWilliam.Wang@arm.com PrefetchEntry() 527753SWilliam.Wang@arm.com { 537753SWilliam.Wang@arm.com // default: 1 cache-line stride 547753SWilliam.Wang@arm.com m_stride = (1 << RubySystem::getBlockSizeBits()); 557753SWilliam.Wang@arm.com m_use_time = Cycles(0); 567753SWilliam.Wang@arm.com m_is_valid = false; 577753SWilliam.Wang@arm.com } 587753SWilliam.Wang@arm.com 597753SWilliam.Wang@arm.com //! The base address for the stream prefetch 607753SWilliam.Wang@arm.com Address m_address; 617753SWilliam.Wang@arm.com 627753SWilliam.Wang@arm.com //! stride distance to get next address from 637753SWilliam.Wang@arm.com int m_stride; 647753SWilliam.Wang@arm.com 657753SWilliam.Wang@arm.com //! the last time that any prefetched request was used 667753SWilliam.Wang@arm.com Cycles m_use_time; 677753SWilliam.Wang@arm.com 687753SWilliam.Wang@arm.com //! valid bit for each stream 697753SWilliam.Wang@arm.com bool m_is_valid; 707753SWilliam.Wang@arm.com 717753SWilliam.Wang@arm.com //! L1D prefetches loads and stores 727753SWilliam.Wang@arm.com RubyRequestType m_type; 737753SWilliam.Wang@arm.com 747753SWilliam.Wang@arm.com //! Bitset for tracking prefetches for which addresses have been 757753SWilliam.Wang@arm.com //! issued, which ones have completed. 767753SWilliam.Wang@arm.com std::bitset<MAX_PF_INFLIGHT> requestIssued; 777753SWilliam.Wang@arm.com std::bitset<MAX_PF_INFLIGHT> requestCompleted; 787753SWilliam.Wang@arm.com}; 797753SWilliam.Wang@arm.com 807753SWilliam.Wang@arm.comclass Prefetcher : public SimObject 817753SWilliam.Wang@arm.com{ 827753SWilliam.Wang@arm.com public: 837753SWilliam.Wang@arm.com typedef PrefetcherParams Params; 847753SWilliam.Wang@arm.com Prefetcher(const Params *p); 857753SWilliam.Wang@arm.com ~Prefetcher(); 867753SWilliam.Wang@arm.com 877753SWilliam.Wang@arm.com void issueNextPrefetch(const Address &address, PrefetchEntry *stream); 887753SWilliam.Wang@arm.com /** 897753SWilliam.Wang@arm.com * Implement the prefetch hit(miss) callback interface. 907753SWilliam.Wang@arm.com * These functions are called by the cache when it hits(misses) 917753SWilliam.Wang@arm.com * on a line with the line's prefetch bit set. If this address 927753SWilliam.Wang@arm.com * hits in m_array we will continue prefetching the stream. 937753SWilliam.Wang@arm.com */ 947753SWilliam.Wang@arm.com void observePfHit(const Address& address); 957753SWilliam.Wang@arm.com void observePfMiss(const Address& address); 967753SWilliam.Wang@arm.com 977753SWilliam.Wang@arm.com /** 987753SWilliam.Wang@arm.com * Observe a memory miss from the cache. 997753SWilliam.Wang@arm.com * 1007753SWilliam.Wang@arm.com * @param address The physical address that missed out of the cache. 1017753SWilliam.Wang@arm.com */ 1027753SWilliam.Wang@arm.com void observeMiss(const Address& address, const RubyRequestType& type); 1037753SWilliam.Wang@arm.com 1047753SWilliam.Wang@arm.com /** 1057753SWilliam.Wang@arm.com * Print out some statistics 1067753SWilliam.Wang@arm.com */ 1077753SWilliam.Wang@arm.com void print(std::ostream& out) const; 1087753SWilliam.Wang@arm.com void setController(AbstractController *_ctrl) 1097753SWilliam.Wang@arm.com { m_controller = _ctrl; } 1107753SWilliam.Wang@arm.com 1117753SWilliam.Wang@arm.com void regStats(); 1127753SWilliam.Wang@arm.com 1137753SWilliam.Wang@arm.com private: 1147753SWilliam.Wang@arm.com /** 1157753SWilliam.Wang@arm.com * Returns an unused stream buffer (or if all are used, returns the 1167753SWilliam.Wang@arm.com * least recently used (accessed) stream buffer). 1177753SWilliam.Wang@arm.com * @return The index of the least recently used stream buffer. 1187753SWilliam.Wang@arm.com */ 1197753SWilliam.Wang@arm.com uint32_t getLRUindex(void); 1207753SWilliam.Wang@arm.com 1217753SWilliam.Wang@arm.com //! clear a non-unit stride prefetcher entry 1227753SWilliam.Wang@arm.com void clearNonunitEntry(uint32_t index); 1237753SWilliam.Wang@arm.com 1247753SWilliam.Wang@arm.com //! allocate a new stream buffer at a specific index 1257753SWilliam.Wang@arm.com void initializeStream(const Address& address, int stride, 1267753SWilliam.Wang@arm.com uint32_t index, const RubyRequestType& type); 1277753SWilliam.Wang@arm.com 1287753SWilliam.Wang@arm.com //! get pointer to the matching stream entry, returns NULL if not found 1297753SWilliam.Wang@arm.com //! index holds the multiple of the stride this address is. 1307753SWilliam.Wang@arm.com PrefetchEntry* getPrefetchEntry(const Address &address, 1317753SWilliam.Wang@arm.com uint32_t &index); 1327753SWilliam.Wang@arm.com 1337753SWilliam.Wang@arm.com /// access a unit stride filter to determine if there is a hit 1347753SWilliam.Wang@arm.com bool accessUnitFilter(std::vector<Address>& filter_table, 1357753SWilliam.Wang@arm.com uint32_t *hit_table, uint32_t &index, const Address &address, 1367753SWilliam.Wang@arm.com int stride, bool &alloc); 1377753SWilliam.Wang@arm.com 1387753SWilliam.Wang@arm.com /// access a unit stride filter to determine if there is a hit 1397753SWilliam.Wang@arm.com bool accessNonunitFilter(const Address& address, int *stride, 1407753SWilliam.Wang@arm.com bool &alloc); 1417753SWilliam.Wang@arm.com 1427753SWilliam.Wang@arm.com //! number of prefetch streams available 1437753SWilliam.Wang@arm.com uint32_t m_num_streams; 1447753SWilliam.Wang@arm.com //! an array of the active prefetch streams 1457753SWilliam.Wang@arm.com std::vector<PrefetchEntry> m_array; 1467753SWilliam.Wang@arm.com 1477753SWilliam.Wang@arm.com //! number of misses I must see before allocating a stream 1487753SWilliam.Wang@arm.com uint32_t m_train_misses; 1497753SWilliam.Wang@arm.com //! number of initial prefetches to startup a stream 1507753SWilliam.Wang@arm.com uint32_t m_num_startup_pfs; 1517753SWilliam.Wang@arm.com //! number of stride filters 1527753SWilliam.Wang@arm.com uint32_t m_num_unit_filters; 1537753SWilliam.Wang@arm.com //! number of non-stride filters 1547753SWilliam.Wang@arm.com uint32_t m_num_nonunit_filters; 1557753SWilliam.Wang@arm.com 1567753SWilliam.Wang@arm.com /// a unit stride filter array: helps reduce BW requirement of 1577753SWilliam.Wang@arm.com /// prefetching 1587753SWilliam.Wang@arm.com std::vector<Address> m_unit_filter; 1597753SWilliam.Wang@arm.com /// a round robin pointer into the unit filter group 1607753SWilliam.Wang@arm.com uint32_t m_unit_filter_index; 1617753SWilliam.Wang@arm.com //! An array used to count the of times particular filter entries 1627753SWilliam.Wang@arm.com //! have been hit 1637753SWilliam.Wang@arm.com uint32_t *m_unit_filter_hit; 1647753SWilliam.Wang@arm.com 1657753SWilliam.Wang@arm.com //! a negative nit stride filter array: helps reduce BW requirement 1667753SWilliam.Wang@arm.com //! of prefetching 1677753SWilliam.Wang@arm.com std::vector<Address> m_negative_filter; 1687753SWilliam.Wang@arm.com /// a round robin pointer into the negative filter group 1697753SWilliam.Wang@arm.com uint32_t m_negative_filter_index; 1707753SWilliam.Wang@arm.com /// An array used to count the of times particular filter entries 1717753SWilliam.Wang@arm.com /// have been hit 1727753SWilliam.Wang@arm.com uint32_t *m_negative_filter_hit; 1737753SWilliam.Wang@arm.com 1747753SWilliam.Wang@arm.com /// a non-unit stride filter array: helps reduce BW requirement of 1757753SWilliam.Wang@arm.com /// prefetching 1767753SWilliam.Wang@arm.com std::vector<Address> m_nonunit_filter; 1777753SWilliam.Wang@arm.com /// An array of strides (in # of cache lines) for the filter entries 1787753SWilliam.Wang@arm.com int *m_nonunit_stride; 1797753SWilliam.Wang@arm.com /// An array used to count the of times particular filter entries 1807753SWilliam.Wang@arm.com /// have been hit 1817753SWilliam.Wang@arm.com uint32_t *m_nonunit_hit; 1827753SWilliam.Wang@arm.com /// a round robin pointer into the unit filter group 1837753SWilliam.Wang@arm.com uint32_t m_nonunit_index; 1847753SWilliam.Wang@arm.com 1857753SWilliam.Wang@arm.com /// Used for allowing prefetches across pages. 1867753SWilliam.Wang@arm.com bool m_prefetch_cross_pages; 1877753SWilliam.Wang@arm.com 1887753SWilliam.Wang@arm.com AbstractController *m_controller; 1897753SWilliam.Wang@arm.com 1907753SWilliam.Wang@arm.com //! Count of accesses to the prefetcher 1917753SWilliam.Wang@arm.com Stats::Scalar numMissObserved; 1927753SWilliam.Wang@arm.com //! Count of prefetch streams allocated 1937753SWilliam.Wang@arm.com Stats::Scalar numAllocatedStreams; 1947753SWilliam.Wang@arm.com //! Count of prefetch requests made 1957753SWilliam.Wang@arm.com Stats::Scalar numPrefetchRequested; 1967753SWilliam.Wang@arm.com //! Count of prefetch requests accepted 1977753SWilliam.Wang@arm.com Stats::Scalar numPrefetchAccepted; 1987753SWilliam.Wang@arm.com //! Count of prefetches dropped 1997753SWilliam.Wang@arm.com Stats::Scalar numDroppedPrefetches; 2007753SWilliam.Wang@arm.com //! Count of successful prefetches 2017753SWilliam.Wang@arm.com Stats::Scalar numHits; 2027753SWilliam.Wang@arm.com //! Count of partial successful prefetches 2037753SWilliam.Wang@arm.com Stats::Scalar numPartialHits; 2047753SWilliam.Wang@arm.com //! Count of pages crossed 2057753SWilliam.Wang@arm.com Stats::Scalar numPagesCrossed; 2067753SWilliam.Wang@arm.com //! Count of misses incurred for blocks that were prefetched 2077753SWilliam.Wang@arm.com Stats::Scalar numMissedPrefetchedBlocks; 2087753SWilliam.Wang@arm.com}; 2097753SWilliam.Wang@arm.com 2107753SWilliam.Wang@arm.com#endif // PREFETCHER_H 2117753SWilliam.Wang@arm.com