indirect_memory.hh (13772:31b71dadc472) indirect_memory.hh (13963:94555f0223ba)
1/**
2 * Copyright (c) 2018 Metempsy Technology Consulting
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 * Authors: Javier Bueno
29 */
30
31/**
32 * Implementation of the Indirect Memory Prefetcher
33 *
34 * References:
35 * IMP: Indirect memory prefetcher.
36 * Yu, X., Hughes, C. J., Satish, N., & Devadas, S. (2015, December).
37 * In Proceedings of the 48th International Symposium on Microarchitecture
38 * (pp. 178-190). ACM.
39 */
40
41#ifndef __MEM_CACHE_PREFETCH_INDIRECT_MEMORY_HH__
42#define __MEM_CACHE_PREFETCH_INDIRECT_MEMORY_HH__
43
44#include <vector>
45
1/**
2 * Copyright (c) 2018 Metempsy Technology Consulting
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 * Authors: Javier Bueno
29 */
30
31/**
32 * Implementation of the Indirect Memory Prefetcher
33 *
34 * References:
35 * IMP: Indirect memory prefetcher.
36 * Yu, X., Hughes, C. J., Satish, N., & Devadas, S. (2015, December).
37 * In Proceedings of the 48th International Symposium on Microarchitecture
38 * (pp. 178-190). ACM.
39 */
40
41#ifndef __MEM_CACHE_PREFETCH_INDIRECT_MEMORY_HH__
42#define __MEM_CACHE_PREFETCH_INDIRECT_MEMORY_HH__
43
44#include <vector>
45
46#include "base/sat_counter.hh"
46#include "mem/cache/prefetch/associative_set.hh"
47#include "mem/cache/prefetch/queued.hh"
48
49struct IndirectMemoryPrefetcherParams;
50
51class IndirectMemoryPrefetcher : public QueuedPrefetcher
52{
53 /** Maximum number of prefetches generated per event */
54 const unsigned int maxPrefetchDistance;
55 /** Shift values considered */
56 const std::vector<int> shiftValues;
57 /** Counter threshold to start prefetching */
58 const unsigned int prefetchThreshold;
47#include "mem/cache/prefetch/associative_set.hh"
48#include "mem/cache/prefetch/queued.hh"
49
50struct IndirectMemoryPrefetcherParams;
51
52class IndirectMemoryPrefetcher : public QueuedPrefetcher
53{
54 /** Maximum number of prefetches generated per event */
55 const unsigned int maxPrefetchDistance;
56 /** Shift values considered */
57 const std::vector<int> shiftValues;
58 /** Counter threshold to start prefetching */
59 const unsigned int prefetchThreshold;
59 /** Maximum value of the confidence indirectCounter */
60 const unsigned int maxIndirectCounterValue;
61 /** streamCounter value to trigger the streaming prefetcher */
62 const int streamCounterThreshold;
63 /** Number of prefetches generated when using the streaming prefetcher */
64 const int streamingDistance;
65
66 /** Prefetch Table Entry */
67 struct PrefetchTableEntry : public TaggedEntry
68 {
69 /* Stream table fields */
70
71 /** Accessed address */
72 Addr address;
73 /** Whether this address is in the secure region */
74 bool secure;
75 /** Confidence counter of the stream */
76 unsigned int streamCounter;
77
78 /* Indirect table fields */
79
80 /** Enable bit of the indirect fields */
81 bool enabled;
82 /** Current index value */
83 int64_t index;
84 /** BaseAddr detected */
85 Addr baseAddr;
86 /** Shift detected */
87 int shift;
88 /** Confidence counter of the indirect fields */
60 /** streamCounter value to trigger the streaming prefetcher */
61 const int streamCounterThreshold;
62 /** Number of prefetches generated when using the streaming prefetcher */
63 const int streamingDistance;
64
65 /** Prefetch Table Entry */
66 struct PrefetchTableEntry : public TaggedEntry
67 {
68 /* Stream table fields */
69
70 /** Accessed address */
71 Addr address;
72 /** Whether this address is in the secure region */
73 bool secure;
74 /** Confidence counter of the stream */
75 unsigned int streamCounter;
76
77 /* Indirect table fields */
78
79 /** Enable bit of the indirect fields */
80 bool enabled;
81 /** Current index value */
82 int64_t index;
83 /** BaseAddr detected */
84 Addr baseAddr;
85 /** Shift detected */
86 int shift;
87 /** Confidence counter of the indirect fields */
89 int indirectCounter;
88 SatCounter indirectCounter;
90 /**
91 * This variable is set to indicate that there has been at least one
92 * match with the current index value. This information is later used
93 * when a new index is updated. If there were no increases in the
94 * indirectCounter, the counter is decremented.
95 */
96 bool increasedIndirectCounter;
97
89 /**
90 * This variable is set to indicate that there has been at least one
91 * match with the current index value. This information is later used
92 * when a new index is updated. If there were no increases in the
93 * indirectCounter, the counter is decremented.
94 */
95 bool increasedIndirectCounter;
96
98 PrefetchTableEntry() : TaggedEntry(), address(0), secure(false),
99 streamCounter(0), enabled(false), index(0), baseAddr(0), shift(0),
100 indirectCounter(0), increasedIndirectCounter(false)
97 PrefetchTableEntry(unsigned indirect_counter_bits)
98 : TaggedEntry(), address(0), secure(false), streamCounter(0),
99 enabled(false), index(0), baseAddr(0), shift(0),
100 indirectCounter(indirect_counter_bits),
101 increasedIndirectCounter(false)
101 {}
102
103 void reset() override {
104 address = 0;
105 secure = false;
106 streamCounter = 0;
107 enabled = false;
108 index = 0;
109 baseAddr = 0;
110 shift = 0;
102 {}
103
104 void reset() override {
105 address = 0;
106 secure = false;
107 streamCounter = 0;
108 enabled = false;
109 index = 0;
110 baseAddr = 0;
111 shift = 0;
111 indirectCounter = 0;
112 indirectCounter.reset();
112 increasedIndirectCounter = false;
113 }
114 };
115 /** Prefetch table */
116 AssociativeSet<PrefetchTableEntry> prefetchTable;
117
118 /** Indirect Pattern Detector entrt */
119 struct IndirectPatternDetectorEntry : public TaggedEntry
120 {
121 /** First index */
122 int64_t idx1;
123 /** Second index */
124 int64_t idx2;
125 /** Valid bit for the second index */
126 bool secondIndexSet;
127 /** Number of misses currently recorded */
128 int numMisses;
129 /**
130 * Potential BaseAddr candidates for each recorded miss.
131 * The number of candidates per miss is determined by the number of
132 * elements in the shiftValues array.
133 */
134 std::vector<std::vector<Addr>> baseAddr;
135
136 IndirectPatternDetectorEntry(unsigned int num_addresses,
137 unsigned int num_shifts)
138 : idx1(0), idx2(0), secondIndexSet(false), numMisses(0),
139 baseAddr(num_addresses, std::vector<Addr>(num_shifts))
140 {}
141
142 void reset() override {
143 idx1 = 0;
144 idx2 = 0;
145 secondIndexSet = false;
146 numMisses = 0;
147 setInvalid();
148 }
149 };
150 /** Indirect Pattern Detector (IPD) table */
151 AssociativeSet<IndirectPatternDetectorEntry> ipd;
152
153 /** Entry currently tracking misses */
154 IndirectPatternDetectorEntry *ipdEntryTrackingMisses;
155
156 /** Byte order used to access the cache */
157 const ByteOrder byteOrder;
158
159 /**
160 * Allocate or update an entry in the IPD
161 * @param pt_entry Pointer to the associated page table entry
162 * @param index Detected first index value
163 */
164 void allocateOrUpdateIPDEntry(const PrefetchTableEntry *pt_entry,
165 int64_t index);
166 /**
167 * Update an IPD entry with a detected miss address, when the first index
168 * is being tracked
169 * @param miss_addr The address that caused the miss
170 */
171 void trackMissIndex1(Addr miss_addr);
172
173 /**
174 * Update an IPD entry with a detected miss address, when the second index
175 * is being tracked
176 * @param miss_addr The address that caused the miss
177 */
178 void trackMissIndex2(Addr miss_addr);
179
180 /**
181 * Checks if an access to the cache matches any active PT entry, if so,
182 * the indirect confidence counter is incremented
183 * @param addr address of the access
184 */
185 void checkAccessMatchOnActiveEntries(Addr addr);
186
187 public:
188 IndirectMemoryPrefetcher(const IndirectMemoryPrefetcherParams *p);
189 ~IndirectMemoryPrefetcher() {}
190
191 void calculatePrefetch(const PrefetchInfo &pfi,
192 std::vector<AddrPriority> &addresses) override;
193};
194#endif//__MEM_CACHE_PREFETCH_INDIRECT_MEMORY_HH__
113 increasedIndirectCounter = false;
114 }
115 };
116 /** Prefetch table */
117 AssociativeSet<PrefetchTableEntry> prefetchTable;
118
119 /** Indirect Pattern Detector entrt */
120 struct IndirectPatternDetectorEntry : public TaggedEntry
121 {
122 /** First index */
123 int64_t idx1;
124 /** Second index */
125 int64_t idx2;
126 /** Valid bit for the second index */
127 bool secondIndexSet;
128 /** Number of misses currently recorded */
129 int numMisses;
130 /**
131 * Potential BaseAddr candidates for each recorded miss.
132 * The number of candidates per miss is determined by the number of
133 * elements in the shiftValues array.
134 */
135 std::vector<std::vector<Addr>> baseAddr;
136
137 IndirectPatternDetectorEntry(unsigned int num_addresses,
138 unsigned int num_shifts)
139 : idx1(0), idx2(0), secondIndexSet(false), numMisses(0),
140 baseAddr(num_addresses, std::vector<Addr>(num_shifts))
141 {}
142
143 void reset() override {
144 idx1 = 0;
145 idx2 = 0;
146 secondIndexSet = false;
147 numMisses = 0;
148 setInvalid();
149 }
150 };
151 /** Indirect Pattern Detector (IPD) table */
152 AssociativeSet<IndirectPatternDetectorEntry> ipd;
153
154 /** Entry currently tracking misses */
155 IndirectPatternDetectorEntry *ipdEntryTrackingMisses;
156
157 /** Byte order used to access the cache */
158 const ByteOrder byteOrder;
159
160 /**
161 * Allocate or update an entry in the IPD
162 * @param pt_entry Pointer to the associated page table entry
163 * @param index Detected first index value
164 */
165 void allocateOrUpdateIPDEntry(const PrefetchTableEntry *pt_entry,
166 int64_t index);
167 /**
168 * Update an IPD entry with a detected miss address, when the first index
169 * is being tracked
170 * @param miss_addr The address that caused the miss
171 */
172 void trackMissIndex1(Addr miss_addr);
173
174 /**
175 * Update an IPD entry with a detected miss address, when the second index
176 * is being tracked
177 * @param miss_addr The address that caused the miss
178 */
179 void trackMissIndex2(Addr miss_addr);
180
181 /**
182 * Checks if an access to the cache matches any active PT entry, if so,
183 * the indirect confidence counter is incremented
184 * @param addr address of the access
185 */
186 void checkAccessMatchOnActiveEntries(Addr addr);
187
188 public:
189 IndirectMemoryPrefetcher(const IndirectMemoryPrefetcherParams *p);
190 ~IndirectMemoryPrefetcher() {}
191
192 void calculatePrefetch(const PrefetchInfo &pfi,
193 std::vector<AddrPriority> &addresses) override;
194};
195#endif//__MEM_CACHE_PREFETCH_INDIRECT_MEMORY_HH__