2 * Copyright (c) 2018 Metempsy Technology Consulting
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.
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.
28 * Authors: Javier Bueno
31 #include "mem/cache/prefetch/delta_correlating_prediction_tables.hh"
33 #include "debug/HWPrefetch.hh"
34 #include "mem/cache/prefetch/associative_set_impl.hh"
35 #include "params/DCPTPrefetcher.hh"
36 #include "params/DeltaCorrelatingPredictionTables.hh"
38 DeltaCorrelatingPredictionTables::DeltaCorrelatingPredictionTables(
39 DeltaCorrelatingPredictionTablesParams
*p
) : SimObject(p
),
40 deltaBits(p
->delta_bits
), deltaMaskBits(p
->delta_mask_bits
),
41 table(p
->table_assoc
, p
->table_entries
, p
->table_indexing_policy
,
42 p
->table_replacement_policy
, DCPTEntry(p
->deltas_per_entry
))
47 DeltaCorrelatingPredictionTables::DCPTEntry::reset()
49 for (auto &delta
: deltas
) {
57 DeltaCorrelatingPredictionTables::DCPTEntry::addAddress(Addr address
,
58 unsigned int delta_bits
)
60 if ((address
- lastAddress
) != 0) {
61 Addr delta
= address
- lastAddress
;
62 // Account for the sign bit
63 Addr max_positive_delta
= (1 << (delta_bits
-1)) - 1;
64 if (address
> lastAddress
) {
65 // check positive delta overflow
66 if (delta
> max_positive_delta
) {
70 // check negative delta overflow
71 if (lastAddress
- address
> (max_positive_delta
+ 1)) {
75 deltas
[deltaPointer
] = delta
;
76 deltaPointer
= (deltaPointer
+ 1) % deltas
.size();
77 lastAddress
= address
;
82 DeltaCorrelatingPredictionTables::DCPTEntry::getCandidates(
83 std::vector
<QueuedPrefetcher::AddrPriority
> &pfs
, unsigned int mask
) const
86 unsigned int last
= (deltaPointer
- 1) % deltas
.size();
87 // second most recent index
88 unsigned int last_prev
= (deltaPointer
- 2) % deltas
.size();
89 int delta_0
= deltas
[last_prev
];
90 int delta_1
= deltas
[last
];
92 // a delta 0 means that it overflowed, we can not match it
93 if (delta_0
== 0 || delta_1
== 0) {
97 // Try to find the two most recent deltas in a previous position on the
98 // delta circular array, if found, start issuing prefetches using the
99 // remaining deltas (adding each delta to the last Addr to generate the
100 // prefetched address.
103 int idx_0
= deltaPointer
+ 1;
104 // second oldest index
105 int idx_1
= deltaPointer
+ 2;
106 for (int i
= 0; i
< deltas
.size() - 2; i
+= 1) {
107 int this_delta_0
= deltas
[(idx_0
+ i
) % deltas
.size()];
108 int this_delta_1
= deltas
[(idx_1
+ i
) % deltas
.size()];
109 if ((this_delta_0
>> mask
) == (delta_0
>> mask
) &&
110 (this_delta_1
>> mask
) == (delta_1
>> mask
)) {
111 Addr addr
= lastAddress
;
112 // Pattern found, issue prefetches with the remaining deltas after
114 i
+= 2; // skip the matching pair
116 int pf_delta
= deltas
[(idx_0
+ i
) % deltas
.size()];
118 pfs
.push_back(QueuedPrefetcher::AddrPriority(addr
, 0));
120 } while (i
< deltas
.size() - 2);
126 DeltaCorrelatingPredictionTables::calculatePrefetch(
127 const BasePrefetcher::PrefetchInfo
&pfi
,
128 std::vector
<QueuedPrefetcher::AddrPriority
> &addresses
)
131 DPRINTF(HWPrefetch
, "Ignoring request with no PC.\n");
134 Addr address
= pfi
.getAddr();
135 Addr pc
= pfi
.getPC();
136 // Look up table entry, is_secure is unused in findEntry because we
137 // index using the pc
138 DCPTEntry
*entry
= table
.findEntry(pc
, false /* unused */);
139 if (entry
!= nullptr) {
140 entry
->addAddress(address
, deltaBits
);
142 entry
->getCandidates(addresses
, deltaMaskBits
);
144 entry
= table
.findVictim(pc
);
146 table
.insertEntry(pc
, false /* unused */, entry
);
148 entry
->lastAddress
= address
;
152 DeltaCorrelatingPredictionTables
*
153 DeltaCorrelatingPredictionTablesParams::create()
155 return new DeltaCorrelatingPredictionTables(this);
158 DCPTPrefetcher::DCPTPrefetcher(const DCPTPrefetcherParams
*p
)
159 : QueuedPrefetcher(p
), dcpt(*p
->dcpt
)
164 DCPTPrefetcher::calculatePrefetch(const PrefetchInfo
&pfi
,
165 std::vector
<AddrPriority
> &addresses
)
167 dcpt
.calculatePrefetch(pfi
, addresses
);
171 DCPTPrefetcherParams::create()
173 return new DCPTPrefetcher(this);