113772Sjavier.bueno@metempsy.com/**
213772Sjavier.bueno@metempsy.com * Copyright (c) 2018 Metempsy Technology Consulting
313772Sjavier.bueno@metempsy.com * All rights reserved.
413772Sjavier.bueno@metempsy.com *
513772Sjavier.bueno@metempsy.com * Redistribution and use in source and binary forms, with or without
613772Sjavier.bueno@metempsy.com * modification, are permitted provided that the following conditions are
713772Sjavier.bueno@metempsy.com * met: redistributions of source code must retain the above copyright
813772Sjavier.bueno@metempsy.com * notice, this list of conditions and the following disclaimer;
913772Sjavier.bueno@metempsy.com * redistributions in binary form must reproduce the above copyright
1013772Sjavier.bueno@metempsy.com * notice, this list of conditions and the following disclaimer in the
1113772Sjavier.bueno@metempsy.com * documentation and/or other materials provided with the distribution;
1213772Sjavier.bueno@metempsy.com * neither the name of the copyright holders nor the names of its
1313772Sjavier.bueno@metempsy.com * contributors may be used to endorse or promote products derived from
1413772Sjavier.bueno@metempsy.com * this software without specific prior written permission.
1513772Sjavier.bueno@metempsy.com *
1613772Sjavier.bueno@metempsy.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1713772Sjavier.bueno@metempsy.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1813772Sjavier.bueno@metempsy.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1913772Sjavier.bueno@metempsy.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2013772Sjavier.bueno@metempsy.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2113772Sjavier.bueno@metempsy.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2213772Sjavier.bueno@metempsy.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2313772Sjavier.bueno@metempsy.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2413772Sjavier.bueno@metempsy.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2513772Sjavier.bueno@metempsy.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2613772Sjavier.bueno@metempsy.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2713772Sjavier.bueno@metempsy.com *
2813772Sjavier.bueno@metempsy.com * Authors: Javier Bueno
2913772Sjavier.bueno@metempsy.com */
3013772Sjavier.bueno@metempsy.com
3113772Sjavier.bueno@metempsy.com/**
3213772Sjavier.bueno@metempsy.com * Implementation of the Indirect Memory Prefetcher
3313772Sjavier.bueno@metempsy.com *
3413772Sjavier.bueno@metempsy.com * References:
3513772Sjavier.bueno@metempsy.com * IMP: Indirect memory prefetcher.
3613772Sjavier.bueno@metempsy.com * Yu, X., Hughes, C. J., Satish, N., & Devadas, S. (2015, December).
3713772Sjavier.bueno@metempsy.com * In Proceedings of the 48th International Symposium on Microarchitecture
3813772Sjavier.bueno@metempsy.com * (pp. 178-190). ACM.
3913772Sjavier.bueno@metempsy.com */
4013772Sjavier.bueno@metempsy.com
4113772Sjavier.bueno@metempsy.com#ifndef __MEM_CACHE_PREFETCH_INDIRECT_MEMORY_HH__
4213772Sjavier.bueno@metempsy.com#define __MEM_CACHE_PREFETCH_INDIRECT_MEMORY_HH__
4313772Sjavier.bueno@metempsy.com
4413772Sjavier.bueno@metempsy.com#include <vector>
4513772Sjavier.bueno@metempsy.com
4613963Sodanrc@yahoo.com.br#include "base/sat_counter.hh"
4713772Sjavier.bueno@metempsy.com#include "mem/cache/prefetch/associative_set.hh"
4813772Sjavier.bueno@metempsy.com#include "mem/cache/prefetch/queued.hh"
4913772Sjavier.bueno@metempsy.com
5013772Sjavier.bueno@metempsy.comstruct IndirectMemoryPrefetcherParams;
5113772Sjavier.bueno@metempsy.com
5213772Sjavier.bueno@metempsy.comclass IndirectMemoryPrefetcher : public QueuedPrefetcher
5313772Sjavier.bueno@metempsy.com{
5413772Sjavier.bueno@metempsy.com    /** Maximum number of prefetches generated per event */
5513772Sjavier.bueno@metempsy.com    const unsigned int maxPrefetchDistance;
5613772Sjavier.bueno@metempsy.com    /** Shift values considered */
5713772Sjavier.bueno@metempsy.com    const std::vector<int> shiftValues;
5813772Sjavier.bueno@metempsy.com    /** Counter threshold to start prefetching */
5913772Sjavier.bueno@metempsy.com    const unsigned int prefetchThreshold;
6013772Sjavier.bueno@metempsy.com    /** streamCounter value to trigger the streaming prefetcher */
6113772Sjavier.bueno@metempsy.com    const int streamCounterThreshold;
6213772Sjavier.bueno@metempsy.com    /** Number of prefetches generated when using the streaming prefetcher */
6313772Sjavier.bueno@metempsy.com    const int streamingDistance;
6413772Sjavier.bueno@metempsy.com
6513772Sjavier.bueno@metempsy.com    /** Prefetch Table Entry */
6613772Sjavier.bueno@metempsy.com    struct PrefetchTableEntry : public TaggedEntry
6713772Sjavier.bueno@metempsy.com    {
6813772Sjavier.bueno@metempsy.com        /* Stream table fields */
6913772Sjavier.bueno@metempsy.com
7013772Sjavier.bueno@metempsy.com        /** Accessed address */
7113772Sjavier.bueno@metempsy.com        Addr address;
7213772Sjavier.bueno@metempsy.com        /** Whether this address is in the secure region */
7313772Sjavier.bueno@metempsy.com        bool secure;
7413772Sjavier.bueno@metempsy.com        /** Confidence counter of the stream */
7513772Sjavier.bueno@metempsy.com        unsigned int streamCounter;
7613772Sjavier.bueno@metempsy.com
7713772Sjavier.bueno@metempsy.com        /* Indirect table fields */
7813772Sjavier.bueno@metempsy.com
7913772Sjavier.bueno@metempsy.com        /** Enable bit of the indirect fields */
8013772Sjavier.bueno@metempsy.com        bool enabled;
8113772Sjavier.bueno@metempsy.com        /** Current index value */
8213772Sjavier.bueno@metempsy.com        int64_t index;
8313772Sjavier.bueno@metempsy.com        /** BaseAddr detected */
8413772Sjavier.bueno@metempsy.com        Addr baseAddr;
8513772Sjavier.bueno@metempsy.com        /** Shift detected */
8613772Sjavier.bueno@metempsy.com        int shift;
8713772Sjavier.bueno@metempsy.com        /** Confidence counter of the indirect fields */
8813963Sodanrc@yahoo.com.br        SatCounter indirectCounter;
8913772Sjavier.bueno@metempsy.com        /**
9013772Sjavier.bueno@metempsy.com         * This variable is set to indicate that there has been at least one
9113772Sjavier.bueno@metempsy.com         * match with the current index value. This information is later used
9213772Sjavier.bueno@metempsy.com         * when a new index is updated. If there were no increases in the
9313772Sjavier.bueno@metempsy.com         * indirectCounter, the counter is decremented.
9413772Sjavier.bueno@metempsy.com         */
9513772Sjavier.bueno@metempsy.com        bool increasedIndirectCounter;
9613772Sjavier.bueno@metempsy.com
9713963Sodanrc@yahoo.com.br        PrefetchTableEntry(unsigned indirect_counter_bits)
9813963Sodanrc@yahoo.com.br            : TaggedEntry(), address(0), secure(false), streamCounter(0),
9913963Sodanrc@yahoo.com.br              enabled(false), index(0), baseAddr(0), shift(0),
10013963Sodanrc@yahoo.com.br              indirectCounter(indirect_counter_bits),
10113963Sodanrc@yahoo.com.br              increasedIndirectCounter(false)
10213772Sjavier.bueno@metempsy.com        {}
10313772Sjavier.bueno@metempsy.com
10413772Sjavier.bueno@metempsy.com        void reset() override {
10513772Sjavier.bueno@metempsy.com            address = 0;
10613772Sjavier.bueno@metempsy.com            secure = false;
10713772Sjavier.bueno@metempsy.com            streamCounter = 0;
10813772Sjavier.bueno@metempsy.com            enabled = false;
10913772Sjavier.bueno@metempsy.com            index = 0;
11013772Sjavier.bueno@metempsy.com            baseAddr = 0;
11113772Sjavier.bueno@metempsy.com            shift = 0;
11213963Sodanrc@yahoo.com.br            indirectCounter.reset();
11313772Sjavier.bueno@metempsy.com            increasedIndirectCounter = false;
11413772Sjavier.bueno@metempsy.com        }
11513772Sjavier.bueno@metempsy.com    };
11613772Sjavier.bueno@metempsy.com    /** Prefetch table */
11713772Sjavier.bueno@metempsy.com    AssociativeSet<PrefetchTableEntry> prefetchTable;
11813772Sjavier.bueno@metempsy.com
11913772Sjavier.bueno@metempsy.com    /** Indirect Pattern Detector entrt */
12013772Sjavier.bueno@metempsy.com    struct IndirectPatternDetectorEntry : public TaggedEntry
12113772Sjavier.bueno@metempsy.com    {
12213772Sjavier.bueno@metempsy.com        /** First index */
12313772Sjavier.bueno@metempsy.com        int64_t idx1;
12413772Sjavier.bueno@metempsy.com        /** Second index */
12513772Sjavier.bueno@metempsy.com        int64_t idx2;
12613772Sjavier.bueno@metempsy.com        /** Valid bit for the second index */
12713772Sjavier.bueno@metempsy.com        bool secondIndexSet;
12813772Sjavier.bueno@metempsy.com        /** Number of misses currently recorded */
12913772Sjavier.bueno@metempsy.com        int numMisses;
13013772Sjavier.bueno@metempsy.com        /**
13113772Sjavier.bueno@metempsy.com         * Potential BaseAddr candidates for each recorded miss.
13213772Sjavier.bueno@metempsy.com         * The number of candidates per miss is determined by the number of
13313772Sjavier.bueno@metempsy.com         * elements in the shiftValues array.
13413772Sjavier.bueno@metempsy.com         */
13513772Sjavier.bueno@metempsy.com        std::vector<std::vector<Addr>> baseAddr;
13613772Sjavier.bueno@metempsy.com
13713772Sjavier.bueno@metempsy.com        IndirectPatternDetectorEntry(unsigned int num_addresses,
13813772Sjavier.bueno@metempsy.com                                     unsigned int num_shifts)
13913772Sjavier.bueno@metempsy.com          : idx1(0), idx2(0), secondIndexSet(false), numMisses(0),
14013772Sjavier.bueno@metempsy.com            baseAddr(num_addresses, std::vector<Addr>(num_shifts))
14113772Sjavier.bueno@metempsy.com        {}
14213772Sjavier.bueno@metempsy.com
14313772Sjavier.bueno@metempsy.com        void reset() override {
14413772Sjavier.bueno@metempsy.com            idx1 = 0;
14513772Sjavier.bueno@metempsy.com            idx2 = 0;
14613772Sjavier.bueno@metempsy.com            secondIndexSet = false;
14713772Sjavier.bueno@metempsy.com            numMisses = 0;
14813772Sjavier.bueno@metempsy.com            setInvalid();
14913772Sjavier.bueno@metempsy.com        }
15013772Sjavier.bueno@metempsy.com    };
15113772Sjavier.bueno@metempsy.com    /** Indirect Pattern Detector (IPD) table */
15213772Sjavier.bueno@metempsy.com    AssociativeSet<IndirectPatternDetectorEntry> ipd;
15313772Sjavier.bueno@metempsy.com
15413772Sjavier.bueno@metempsy.com    /** Entry currently tracking misses */
15513772Sjavier.bueno@metempsy.com    IndirectPatternDetectorEntry *ipdEntryTrackingMisses;
15613772Sjavier.bueno@metempsy.com
15713772Sjavier.bueno@metempsy.com    /** Byte order used to access the cache */
15813772Sjavier.bueno@metempsy.com    const ByteOrder byteOrder;
15913772Sjavier.bueno@metempsy.com
16013772Sjavier.bueno@metempsy.com    /**
16113772Sjavier.bueno@metempsy.com     * Allocate or update an entry in the IPD
16213772Sjavier.bueno@metempsy.com     * @param pt_entry Pointer to the associated page table entry
16313772Sjavier.bueno@metempsy.com     * @param index Detected first index value
16413772Sjavier.bueno@metempsy.com     */
16513772Sjavier.bueno@metempsy.com    void allocateOrUpdateIPDEntry(const PrefetchTableEntry *pt_entry,
16613772Sjavier.bueno@metempsy.com                                  int64_t index);
16713772Sjavier.bueno@metempsy.com    /**
16813772Sjavier.bueno@metempsy.com     * Update an IPD entry with a detected miss address, when the first index
16913772Sjavier.bueno@metempsy.com     * is being tracked
17013772Sjavier.bueno@metempsy.com     * @param miss_addr The address that caused the miss
17113772Sjavier.bueno@metempsy.com     */
17213772Sjavier.bueno@metempsy.com    void trackMissIndex1(Addr miss_addr);
17313772Sjavier.bueno@metempsy.com
17413772Sjavier.bueno@metempsy.com    /**
17513772Sjavier.bueno@metempsy.com     * Update an IPD entry with a detected miss address, when the second index
17613772Sjavier.bueno@metempsy.com     * is being tracked
17713772Sjavier.bueno@metempsy.com     * @param miss_addr The address that caused the miss
17813772Sjavier.bueno@metempsy.com     */
17913772Sjavier.bueno@metempsy.com    void trackMissIndex2(Addr miss_addr);
18013772Sjavier.bueno@metempsy.com
18113772Sjavier.bueno@metempsy.com    /**
18213772Sjavier.bueno@metempsy.com     * Checks if an access to the cache matches any active PT entry, if so,
18313772Sjavier.bueno@metempsy.com     * the indirect confidence counter is incremented
18413772Sjavier.bueno@metempsy.com     * @param addr address of the access
18513772Sjavier.bueno@metempsy.com     */
18613772Sjavier.bueno@metempsy.com    void checkAccessMatchOnActiveEntries(Addr addr);
18713772Sjavier.bueno@metempsy.com
18813772Sjavier.bueno@metempsy.com  public:
18913772Sjavier.bueno@metempsy.com    IndirectMemoryPrefetcher(const IndirectMemoryPrefetcherParams *p);
19013772Sjavier.bueno@metempsy.com    ~IndirectMemoryPrefetcher() {}
19113772Sjavier.bueno@metempsy.com
19213772Sjavier.bueno@metempsy.com    void calculatePrefetch(const PrefetchInfo &pfi,
19313772Sjavier.bueno@metempsy.com                           std::vector<AddrPriority> &addresses) override;
19413772Sjavier.bueno@metempsy.com};
19513772Sjavier.bueno@metempsy.com#endif//__MEM_CACHE_PREFETCH_INDIRECT_MEMORY_HH__
196