tlb_coalescer.hh revision 12697
111308Santhony.gutierrez@amd.com/* 211308Santhony.gutierrez@amd.com * Copyright (c) 2011-2015 Advanced Micro Devices, Inc. 311308Santhony.gutierrez@amd.com * All rights reserved. 411308Santhony.gutierrez@amd.com * 511308Santhony.gutierrez@amd.com * For use for simulation and test purposes only 611308Santhony.gutierrez@amd.com * 711308Santhony.gutierrez@amd.com * Redistribution and use in source and binary forms, with or without 811308Santhony.gutierrez@amd.com * modification, are permitted provided that the following conditions are met: 911308Santhony.gutierrez@amd.com * 1011308Santhony.gutierrez@amd.com * 1. Redistributions of source code must retain the above copyright notice, 1111308Santhony.gutierrez@amd.com * this list of conditions and the following disclaimer. 1211308Santhony.gutierrez@amd.com * 1311308Santhony.gutierrez@amd.com * 2. Redistributions in binary form must reproduce the above copyright notice, 1411308Santhony.gutierrez@amd.com * this list of conditions and the following disclaimer in the documentation 1511308Santhony.gutierrez@amd.com * and/or other materials provided with the distribution. 1611308Santhony.gutierrez@amd.com * 1712697Santhony.gutierrez@amd.com * 3. Neither the name of the copyright holder nor the names of its 1812697Santhony.gutierrez@amd.com * contributors may be used to endorse or promote products derived from this 1912697Santhony.gutierrez@amd.com * software without specific prior written permission. 2011308Santhony.gutierrez@amd.com * 2111308Santhony.gutierrez@amd.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 2211308Santhony.gutierrez@amd.com * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2311308Santhony.gutierrez@amd.com * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2411308Santhony.gutierrez@amd.com * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 2511308Santhony.gutierrez@amd.com * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2611308Santhony.gutierrez@amd.com * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2711308Santhony.gutierrez@amd.com * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2811308Santhony.gutierrez@amd.com * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2911308Santhony.gutierrez@amd.com * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 3011308Santhony.gutierrez@amd.com * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 3111308Santhony.gutierrez@amd.com * POSSIBILITY OF SUCH DAMAGE. 3211308Santhony.gutierrez@amd.com * 3312697Santhony.gutierrez@amd.com * Authors: Lisa Hsu 3411308Santhony.gutierrez@amd.com */ 3511308Santhony.gutierrez@amd.com 3611308Santhony.gutierrez@amd.com#ifndef __TLB_COALESCER_HH__ 3711308Santhony.gutierrez@amd.com#define __TLB_COALESCER_HH__ 3811308Santhony.gutierrez@amd.com 3911308Santhony.gutierrez@amd.com#include <list> 4011308Santhony.gutierrez@amd.com#include <queue> 4111308Santhony.gutierrez@amd.com#include <string> 4211308Santhony.gutierrez@amd.com#include <vector> 4311308Santhony.gutierrez@amd.com 4411308Santhony.gutierrez@amd.com#include "arch/generic/tlb.hh" 4511308Santhony.gutierrez@amd.com#include "arch/isa.hh" 4611308Santhony.gutierrez@amd.com#include "arch/isa_traits.hh" 4711308Santhony.gutierrez@amd.com#include "arch/x86/pagetable.hh" 4811308Santhony.gutierrez@amd.com#include "arch/x86/regs/segment.hh" 4912334Sgabeblack@google.com#include "base/logging.hh" 5011308Santhony.gutierrez@amd.com#include "base/statistics.hh" 5111308Santhony.gutierrez@amd.com#include "gpu-compute/gpu_tlb.hh" 5211308Santhony.gutierrez@amd.com#include "mem/mem_object.hh" 5311308Santhony.gutierrez@amd.com#include "mem/port.hh" 5411308Santhony.gutierrez@amd.com#include "mem/request.hh" 5511308Santhony.gutierrez@amd.com#include "params/TLBCoalescer.hh" 5611308Santhony.gutierrez@amd.com 5711308Santhony.gutierrez@amd.comclass BaseTLB; 5811308Santhony.gutierrez@amd.comclass Packet; 5911308Santhony.gutierrez@amd.comclass ThreadContext; 6011308Santhony.gutierrez@amd.com 6111308Santhony.gutierrez@amd.com/** 6211308Santhony.gutierrez@amd.com * The TLBCoalescer is a MemObject sitting on the front side (CPUSide) of 6311308Santhony.gutierrez@amd.com * each TLB. It receives packets and issues coalesced requests to the 6411308Santhony.gutierrez@amd.com * TLB below it. It controls how requests are coalesced (the rules) 6511308Santhony.gutierrez@amd.com * and the permitted number of TLB probes per cycle (i.e., how many 6611308Santhony.gutierrez@amd.com * coalesced requests it feeds the TLB per cycle). 6711308Santhony.gutierrez@amd.com */ 6811308Santhony.gutierrez@amd.comclass TLBCoalescer : public MemObject 6911308Santhony.gutierrez@amd.com{ 7011308Santhony.gutierrez@amd.com protected: 7111308Santhony.gutierrez@amd.com // TLB clock: will inherit clock from shader's clock period in terms 7211308Santhony.gutierrez@amd.com // of nuber of ticks of curTime (aka global simulation clock) 7311308Santhony.gutierrez@amd.com // The assignment of TLB clock from shader clock is done in the 7411308Santhony.gutierrez@amd.com // python config files. 7511308Santhony.gutierrez@amd.com int clock; 7611308Santhony.gutierrez@amd.com 7711308Santhony.gutierrez@amd.com public: 7811308Santhony.gutierrez@amd.com typedef TLBCoalescerParams Params; 7911308Santhony.gutierrez@amd.com TLBCoalescer(const Params *p); 8011308Santhony.gutierrez@amd.com ~TLBCoalescer() { } 8111308Santhony.gutierrez@amd.com 8211308Santhony.gutierrez@amd.com // Number of TLB probes per cycle. Parameterizable - default 2. 8311308Santhony.gutierrez@amd.com int TLBProbesPerCycle; 8411308Santhony.gutierrez@amd.com 8511308Santhony.gutierrez@amd.com // Consider coalescing across that many ticks. 8611308Santhony.gutierrez@amd.com // Paraemterizable - default 1. 8711308Santhony.gutierrez@amd.com int coalescingWindow; 8811308Santhony.gutierrez@amd.com 8911308Santhony.gutierrez@amd.com // Each coalesced request consists of multiple packets 9011308Santhony.gutierrez@amd.com // that all fall within the same virtual page 9111308Santhony.gutierrez@amd.com typedef std::vector<PacketPtr> coalescedReq; 9211308Santhony.gutierrez@amd.com 9311308Santhony.gutierrez@amd.com // disables coalescing when true 9411308Santhony.gutierrez@amd.com bool disableCoalescing; 9511308Santhony.gutierrez@amd.com 9611308Santhony.gutierrez@amd.com /* 9711308Santhony.gutierrez@amd.com * This is a hash map with <tick_index> as a key. 9811308Santhony.gutierrez@amd.com * It contains a vector of coalescedReqs per <tick_index>. 9911308Santhony.gutierrez@amd.com * Requests are buffered here until they can be issued to 10011308Santhony.gutierrez@amd.com * the TLB, at which point they are copied to the 10111308Santhony.gutierrez@amd.com * issuedTranslationsTable hash map. 10211308Santhony.gutierrez@amd.com * 10311308Santhony.gutierrez@amd.com * In terms of coalescing, we coalesce requests in a given 10411308Santhony.gutierrez@amd.com * window of x cycles by using tick_index = issueTime/x as a 10511308Santhony.gutierrez@amd.com * key, where x = coalescingWindow. issueTime is the issueTime 10611308Santhony.gutierrez@amd.com * of the pkt from the ComputeUnit's perspective, but another 10711308Santhony.gutierrez@amd.com * option is to change it to curTick(), so we coalesce based 10811308Santhony.gutierrez@amd.com * on the receive time. 10911308Santhony.gutierrez@amd.com */ 11011308Santhony.gutierrez@amd.com typedef std::unordered_map<int64_t, std::vector<coalescedReq>> CoalescingFIFO; 11111308Santhony.gutierrez@amd.com 11211308Santhony.gutierrez@amd.com CoalescingFIFO coalescerFIFO; 11311308Santhony.gutierrez@amd.com 11411308Santhony.gutierrez@amd.com /* 11511308Santhony.gutierrez@amd.com * issuedTranslationsTabler: a hash_map indexed by virtual page 11611308Santhony.gutierrez@amd.com * address. Each hash_map entry has a vector of PacketPtr associated 11711308Santhony.gutierrez@amd.com * with it denoting the different packets that share an outstanding 11811308Santhony.gutierrez@amd.com * coalesced translation request for the same virtual page. 11911308Santhony.gutierrez@amd.com * 12011308Santhony.gutierrez@amd.com * The rules that determine which requests we can coalesce are 12111308Santhony.gutierrez@amd.com * specified in the canCoalesce() method. 12211308Santhony.gutierrez@amd.com */ 12311308Santhony.gutierrez@amd.com typedef std::unordered_map<Addr, coalescedReq> CoalescingTable; 12411308Santhony.gutierrez@amd.com 12511308Santhony.gutierrez@amd.com CoalescingTable issuedTranslationsTable; 12611308Santhony.gutierrez@amd.com 12711308Santhony.gutierrez@amd.com // number of packets the coalescer receives 12811308Santhony.gutierrez@amd.com Stats::Scalar uncoalescedAccesses; 12911308Santhony.gutierrez@amd.com // number packets the coalescer send to the TLB 13011308Santhony.gutierrez@amd.com Stats::Scalar coalescedAccesses; 13111308Santhony.gutierrez@amd.com 13211308Santhony.gutierrez@amd.com // Number of cycles the coalesced requests spend waiting in 13311308Santhony.gutierrez@amd.com // coalescerFIFO. For each packet the coalescer receives we take into 13411308Santhony.gutierrez@amd.com // account the number of all uncoalesced requests this pkt "represents" 13511308Santhony.gutierrez@amd.com Stats::Scalar queuingCycles; 13611308Santhony.gutierrez@amd.com 13711308Santhony.gutierrez@amd.com // On average how much time a request from the 13811308Santhony.gutierrez@amd.com // uncoalescedAccesses that reaches the TLB 13911308Santhony.gutierrez@amd.com // spends waiting? 14011308Santhony.gutierrez@amd.com Stats::Scalar localqueuingCycles; 14111308Santhony.gutierrez@amd.com // localqueuingCycles/uncoalescedAccesses 14211308Santhony.gutierrez@amd.com Stats::Formula localLatency; 14311308Santhony.gutierrez@amd.com 14411308Santhony.gutierrez@amd.com bool canCoalesce(PacketPtr pkt1, PacketPtr pkt2); 14511308Santhony.gutierrez@amd.com void updatePhysAddresses(PacketPtr pkt); 14611308Santhony.gutierrez@amd.com void regStats(); 14711308Santhony.gutierrez@amd.com 14811308Santhony.gutierrez@amd.com // Clock related functions. Maps to-and-from 14911308Santhony.gutierrez@amd.com // Simulation ticks and object clocks. 15011308Santhony.gutierrez@amd.com Tick frequency() const { return SimClock::Frequency / clock; } 15111308Santhony.gutierrez@amd.com Tick ticks(int numCycles) const { return (Tick)clock * numCycles; } 15211308Santhony.gutierrez@amd.com Tick curCycle() const { return curTick() / clock; } 15311308Santhony.gutierrez@amd.com Tick tickToCycles(Tick val) const { return val / clock;} 15411308Santhony.gutierrez@amd.com 15511308Santhony.gutierrez@amd.com class CpuSidePort : public SlavePort 15611308Santhony.gutierrez@amd.com { 15711308Santhony.gutierrez@amd.com public: 15811308Santhony.gutierrez@amd.com CpuSidePort(const std::string &_name, TLBCoalescer *tlb_coalescer, 15911308Santhony.gutierrez@amd.com PortID _index) 16011308Santhony.gutierrez@amd.com : SlavePort(_name, tlb_coalescer), coalescer(tlb_coalescer), 16111308Santhony.gutierrez@amd.com index(_index) { } 16211308Santhony.gutierrez@amd.com 16311308Santhony.gutierrez@amd.com protected: 16411308Santhony.gutierrez@amd.com TLBCoalescer *coalescer; 16511308Santhony.gutierrez@amd.com int index; 16611308Santhony.gutierrez@amd.com 16711308Santhony.gutierrez@amd.com virtual bool recvTimingReq(PacketPtr pkt); 16811308Santhony.gutierrez@amd.com virtual Tick recvAtomic(PacketPtr pkt) { return 0; } 16911308Santhony.gutierrez@amd.com virtual void recvFunctional(PacketPtr pkt); 17011308Santhony.gutierrez@amd.com virtual void recvRangeChange() { } 17111308Santhony.gutierrez@amd.com virtual void recvReqRetry(); 17211308Santhony.gutierrez@amd.com 17311308Santhony.gutierrez@amd.com virtual void 17411308Santhony.gutierrez@amd.com recvRespRetry() 17511308Santhony.gutierrez@amd.com { 17611308Santhony.gutierrez@amd.com fatal("recvRespRetry() is not implemented in the TLB coalescer.\n"); 17711308Santhony.gutierrez@amd.com } 17811308Santhony.gutierrez@amd.com 17911308Santhony.gutierrez@amd.com virtual AddrRangeList getAddrRanges() const; 18011308Santhony.gutierrez@amd.com }; 18111308Santhony.gutierrez@amd.com 18211308Santhony.gutierrez@amd.com class MemSidePort : public MasterPort 18311308Santhony.gutierrez@amd.com { 18411308Santhony.gutierrez@amd.com public: 18511308Santhony.gutierrez@amd.com MemSidePort(const std::string &_name, TLBCoalescer *tlb_coalescer, 18611308Santhony.gutierrez@amd.com PortID _index) 18711308Santhony.gutierrez@amd.com : MasterPort(_name, tlb_coalescer), coalescer(tlb_coalescer), 18811308Santhony.gutierrez@amd.com index(_index) { } 18911308Santhony.gutierrez@amd.com 19011308Santhony.gutierrez@amd.com std::deque<PacketPtr> retries; 19111308Santhony.gutierrez@amd.com 19211308Santhony.gutierrez@amd.com protected: 19311308Santhony.gutierrez@amd.com TLBCoalescer *coalescer; 19411308Santhony.gutierrez@amd.com int index; 19511308Santhony.gutierrez@amd.com 19611308Santhony.gutierrez@amd.com virtual bool recvTimingResp(PacketPtr pkt); 19711308Santhony.gutierrez@amd.com virtual Tick recvAtomic(PacketPtr pkt) { return 0; } 19811308Santhony.gutierrez@amd.com virtual void recvFunctional(PacketPtr pkt); 19911308Santhony.gutierrez@amd.com virtual void recvRangeChange() { } 20011308Santhony.gutierrez@amd.com virtual void recvReqRetry(); 20111308Santhony.gutierrez@amd.com 20211308Santhony.gutierrez@amd.com virtual void 20311308Santhony.gutierrez@amd.com recvRespRetry() 20411308Santhony.gutierrez@amd.com { 20511308Santhony.gutierrez@amd.com fatal("recvRespRetry() not implemented in TLB coalescer"); 20611308Santhony.gutierrez@amd.com } 20711308Santhony.gutierrez@amd.com }; 20811308Santhony.gutierrez@amd.com 20911308Santhony.gutierrez@amd.com // Coalescer slave ports on the cpu Side 21011308Santhony.gutierrez@amd.com std::vector<CpuSidePort*> cpuSidePort; 21111308Santhony.gutierrez@amd.com // Coalescer master ports on the memory side 21211308Santhony.gutierrez@amd.com std::vector<MemSidePort*> memSidePort; 21311308Santhony.gutierrez@amd.com 21411308Santhony.gutierrez@amd.com BaseMasterPort& getMasterPort(const std::string &if_name, PortID idx); 21511308Santhony.gutierrez@amd.com BaseSlavePort& getSlavePort(const std::string &if_name, PortID idx); 21611308Santhony.gutierrez@amd.com 21712126Sspwilson2@wisc.edu void processProbeTLBEvent(); 21812126Sspwilson2@wisc.edu /// This event issues the TLB probes 21912126Sspwilson2@wisc.edu EventFunctionWrapper probeTLBEvent; 22011308Santhony.gutierrez@amd.com 22112126Sspwilson2@wisc.edu void processCleanupEvent(); 22212126Sspwilson2@wisc.edu /// The cleanupEvent is scheduled after a TLBEvent triggers 22312126Sspwilson2@wisc.edu /// in order to free memory and do the required clean-up 22412126Sspwilson2@wisc.edu EventFunctionWrapper cleanupEvent; 22511308Santhony.gutierrez@amd.com 22611308Santhony.gutierrez@amd.com // this FIFO queue keeps track of the virt. page 22711308Santhony.gutierrez@amd.com // addresses that are pending cleanup 22811308Santhony.gutierrez@amd.com std::queue<Addr> cleanupQueue; 22911308Santhony.gutierrez@amd.com}; 23011308Santhony.gutierrez@amd.com 23111308Santhony.gutierrez@amd.com#endif // __TLB_COALESCER_HH__ 232