queued.cc (13428:ceddb3964aea) | queued.cc (13551:f352df8e2863) |
---|---|
1/* 2 * Copyright (c) 2014-2015 ARM Limited 3 * All rights reserved 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software --- 50 unchanged lines hidden (view full) --- 59{ 60 // Delete the queued prefetch packets 61 for (DeferredPacket &p : pfq) { 62 delete p.pkt; 63 } 64} 65 66void | 1/* 2 * Copyright (c) 2014-2015 ARM Limited 3 * All rights reserved 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software --- 50 unchanged lines hidden (view full) --- 59{ 60 // Delete the queued prefetch packets 61 for (DeferredPacket &p : pfq) { 62 delete p.pkt; 63 } 64} 65 66void |
67QueuedPrefetcher::notify(const PacketPtr &pkt) | 67QueuedPrefetcher::notify(const PacketPtr &pkt, const PrefetchInfo &pfi) |
68{ | 68{ |
69 // Verify this access type is observed by prefetcher 70 if (observeAccess(pkt)) { 71 Addr blk_addr = pkt->getBlockAddr(blkSize); 72 bool is_secure = pkt->isSecure(); | 69 Addr blk_addr = blockAddress(pfi.getAddr()); 70 bool is_secure = pfi.isSecure(); |
73 | 71 |
74 // Squash queued prefetches if demand miss to same line 75 if (queueSquash) { 76 auto itr = pfq.begin(); 77 while (itr != pfq.end()) { 78 if (itr->pkt->getAddr() == blk_addr && 79 itr->pkt->isSecure() == is_secure) { 80 delete itr->pkt; 81 itr = pfq.erase(itr); 82 } else { 83 ++itr; 84 } | 72 // Squash queued prefetches if demand miss to same line 73 if (queueSquash) { 74 auto itr = pfq.begin(); 75 while (itr != pfq.end()) { 76 if (itr->pfInfo.getAddr() == blk_addr && 77 itr->pfInfo.isSecure() == is_secure) { 78 delete itr->pkt; 79 itr = pfq.erase(itr); 80 } else { 81 ++itr; |
85 } 86 } | 82 } 83 } |
84 } |
|
87 | 85 |
88 // Calculate prefetches given this access 89 std::vector<AddrPriority> addresses; 90 calculatePrefetch(pkt, addresses); | 86 // Calculate prefetches given this access 87 std::vector 88 calculatePrefetch(pfi, addresses); |
91 | 89 |
92 // Queue up generated prefetches 93 for (AddrPriority& pf_info : addresses) { 94 // Block align prefetch address 95 pf_info.first = blockAddress(pf_info.first); | 90 // Queue up generated prefetches 91 for (AddrPriority& addr_prio : addresses) { |
96 | 92 |
97 pfIdentified++; 98 DPRINTF(HWPrefetch, "Found a pf candidate addr: %#x, " 99 "inserting into prefetch queue.\n", pf_info.first); | 93 // Block align prefetch address 94 addr_prio.first = blockAddress(addr_prio.first); |
100 | 95 |
101 // Create and insert the request 102 PacketPtr pf_pkt = insert(pf_info, is_secure); | 96 PrefetchInfo new_pfi(pfi,addr_prio.first); |
103 | 97 |
104 if (pf_pkt != nullptr) { 105 if (tagPrefetch && pkt->req->hasPC()) { 106 // Tag prefetch packet with accessing pc 107 pf_pkt->req->setPC(pkt->req->getPC()); 108 } 109 } 110 } | 98 pfIdentified++; 99 DPRINTF(HWPrefetch, "Found a pf candidate addr: %#x, " 100 "inserting into prefetch queue.\n", new_pfi.getAddr()); 101 102 // Create and insert the request 103 insert(pkt, new_pfi, addr_prio.second); |
111 } 112} 113 114PacketPtr 115QueuedPrefetcher::getPacket() 116{ 117 DPRINTF(HWPrefetch, "Requesting a prefetch to issue.\n"); 118 119 if (pfq.empty()) { 120 DPRINTF(HWPrefetch, "No hardware prefetches available.\n"); 121 return nullptr; 122 } 123 | 104 } 105} 106 107PacketPtr 108QueuedPrefetcher::getPacket() 109{ 110 DPRINTF(HWPrefetch, "Requesting a prefetch to issue.\n"); 111 112 if (pfq.empty()) { 113 DPRINTF(HWPrefetch, "No hardware prefetches available.\n"); 114 return nullptr; 115 } 116 |
124 PacketPtr pkt = pfq.begin()->pkt; | 117 PacketPtr pkt = pfq.front().pkt; |
125 pfq.pop_front(); 126 127 pfIssued++; 128 assert(pkt != nullptr); 129 DPRINTF(HWPrefetch, "Generating prefetch for %#x.\n", pkt->getAddr()); 130 return pkt; 131} 132 133QueuedPrefetcher::const_iterator | 118 pfq.pop_front(); 119 120 pfIssued++; 121 assert(pkt != nullptr); 122 DPRINTF(HWPrefetch, "Generating prefetch for %#x.\n", pkt->getAddr()); 123 return pkt; 124} 125 126QueuedPrefetcher::const_iterator |
134QueuedPrefetcher::inPrefetch(Addr address, bool is_secure) const | 127QueuedPrefetcher::inPrefetch(const PrefetchInfo &pfi) const |
135{ 136 for (const_iterator dp = pfq.begin(); dp != pfq.end(); dp++) { | 128{ 129 for (const_iterator dp = pfq.begin(); dp != pfq.end(); dp++) { |
137 if ((*dp).pkt->getAddr() == address && 138 (*dp).pkt->isSecure() == is_secure) return dp; | 130 if (dp->pfInfo.sameAddr(pfi)) return dp; |
139 } 140 141 return pfq.end(); 142} 143 144QueuedPrefetcher::iterator | 131 } 132 133 return pfq.end(); 134} 135 136QueuedPrefetcher::iterator |
145QueuedPrefetcher::inPrefetch(Addr address, bool is_secure) | 137QueuedPrefetcher::inPrefetch(const PrefetchInfo &pfi) |
146{ 147 for (iterator dp = pfq.begin(); dp != pfq.end(); dp++) { | 138{ 139 for (iterator dp = pfq.begin(); dp != pfq.end(); dp++) { |
148 if (dp->pkt->getAddr() == address && 149 dp->pkt->isSecure() == is_secure) return dp; | 140 if (dp->pfInfo.sameAddr(pfi)) return dp; |
150 } 151 152 return pfq.end(); 153} 154 155void 156QueuedPrefetcher::regStats() 157{ --- 15 unchanged lines hidden (view full) --- 173 .name(name() + ".pfRemovedFull") 174 .desc("number of prefetches dropped due to prefetch queue size"); 175 176 pfSpanPage 177 .name(name() + ".pfSpanPage") 178 .desc("number of prefetches not generated due to page crossing"); 179} 180 | 141 } 142 143 return pfq.end(); 144} 145 146void 147QueuedPrefetcher::regStats() 148{ --- 15 unchanged lines hidden (view full) --- 164 .name(name() + ".pfRemovedFull") 165 .desc("number of prefetches dropped due to prefetch queue size"); 166 167 pfSpanPage 168 .name(name() + ".pfSpanPage") 169 .desc("number of prefetches not generated due to page crossing"); 170} 171 |
181PacketPtr 182QueuedPrefetcher::insert(AddrPriority &pf_info, bool is_secure) | 172void 173QueuedPrefetcher::insert(const PacketPtr &pkt, PrefetchInfo &new_pfi, 174 int32_t priority) |
183{ 184 if (queueFilter) { | 175{ 176 if (queueFilter) { |
185 iterator it = inPrefetch(pf_info.first, is_secure); | 177 iterator it = inPrefetch(new_pfi); |
186 /* If the address is already in the queue, update priority and leave */ 187 if (it != pfq.end()) { 188 pfBufferHit++; | 178 /* If the address is already in the queue, update priority and leave */ 179 if (it != pfq.end()) { 180 pfBufferHit++; |
189 if (it->priority < pf_info.second) { | 181 if (it->priority < priority) { |
190 /* Update priority value and position in the queue */ | 182 /* Update priority value and position in the queue */ |
191 it->priority = pf_info.second; | 183 it->priority = priority; |
192 iterator prev = it; 193 bool cont = true; 194 while (cont && prev != pfq.begin()) { 195 prev--; 196 /* If the packet has higher priority, swap */ 197 if (*it > *prev) { 198 std::swap(*it, *prev); 199 it = prev; 200 } 201 } 202 DPRINTF(HWPrefetch, "Prefetch addr already in " 203 "prefetch queue, priority updated\n"); 204 } else { 205 DPRINTF(HWPrefetch, "Prefetch addr already in " 206 "prefetch queue\n"); 207 } | 184 iterator prev = it; 185 bool cont = true; 186 while (cont && prev != pfq.begin()) { 187 prev--; 188 /* If the packet has higher priority, swap */ 189 if (*it > *prev) { 190 std::swap(*it, *prev); 191 it = prev; 192 } 193 } 194 DPRINTF(HWPrefetch, "Prefetch addr already in " 195 "prefetch queue, priority updated\n"); 196 } else { 197 DPRINTF(HWPrefetch, "Prefetch addr already in " 198 "prefetch queue\n"); 199 } |
208 return nullptr; | 200 return; |
209 } 210 } 211 | 201 } 202 } 203 |
212 if (cacheSnoop && (inCache(pf_info.first, is_secure) || 213 inMissQueue(pf_info.first, is_secure))) { | 204 Addr target_addr = new_pfi.getAddr(); 205 if (useVirtualAddresses) { 206 assert(pkt->req->hasPaddr()); 207 //if we trained with virtual addresses, compute the phsysical address 208 if (new_pfi.getAddr() >= pkt->req->getVaddr()) { 209 //positive stride 210 target_addr = pkt->req->getPaddr() + 211 (new_pfi.getAddr() - pkt->req->getVaddr()); 212 } else { 213 //negative stride 214 target_addr = pkt->req->getPaddr() - 215 (pkt->req->getVaddr() - new_pfi.getAddr()); 216 } 217 } 218 219 if (cacheSnoop && (inCache(target_addr, new_pfi.isSecure()) || 220 inMissQueue(target_addr, new_pfi.isSecure()))) { |
214 pfInCache++; 215 DPRINTF(HWPrefetch, "Dropping redundant in " | 221 pfInCache++; 222 DPRINTF(HWPrefetch, "Dropping redundant in " |
216 "cache/MSHR prefetch addr:%#x\n", pf_info.first); 217 return nullptr; | 223 "cache/MSHR prefetch addr:%#x\n", target_addr); 224 return; |
218 } 219 220 /* Create a prefetch memory request */ 221 RequestPtr pf_req = | 225 } 226 227 /* Create a prefetch memory request */ 228 RequestPtr pf_req = |
222 std::make_shared<Request>(pf_info.first, blkSize, 0, masterId); | 229 std::make_shared<Request>(target_addr, blkSize, 0, masterId); |
223 | 230 |
224 if (is_secure) { | 231 if (new_pfi.isSecure()) { |
225 pf_req->setFlags(Request::SECURE); 226 } 227 pf_req->taskId(ContextSwitchTaskId::Prefetcher); 228 PacketPtr pf_pkt = new Packet(pf_req, MemCmd::HardPFReq); 229 pf_pkt->allocate(); | 232 pf_req->setFlags(Request::SECURE); 233 } 234 pf_req->taskId(ContextSwitchTaskId::Prefetcher); 235 PacketPtr pf_pkt = new Packet(pf_req, MemCmd::HardPFReq); 236 pf_pkt->allocate(); |
237 if (tagPrefetch && new_pfi.hasPC()) { 238 // Tag prefetch packet with accessing pc 239 pf_pkt->req->setPC(new_pfi.getPC()); 240 } |
|
230 231 /* Verify prefetch buffer space for request */ 232 if (pfq.size() == queueSize) { 233 pfRemovedFull++; 234 /* Lowest priority packet */ 235 iterator it = pfq.end(); 236 panic_if (it == pfq.begin(), "Prefetch queue is both full and empty!"); 237 --it; 238 /* Look for oldest in that level of priority */ 239 panic_if (it == pfq.begin(), "Prefetch queue is full with 1 element!"); 240 iterator prev = it; 241 bool cont = true; 242 /* While not at the head of the queue */ 243 while (cont && prev != pfq.begin()) { 244 prev--; 245 /* While at the same level of priority */ | 241 242 /* Verify prefetch buffer space for request */ 243 if (pfq.size() == queueSize) { 244 pfRemovedFull++; 245 /* Lowest priority packet */ 246 iterator it = pfq.end(); 247 panic_if (it == pfq.begin(), "Prefetch queue is both full and empty!"); 248 --it; 249 /* Look for oldest in that level of priority */ 250 panic_if (it == pfq.begin(), "Prefetch queue is full with 1 element!"); 251 iterator prev = it; 252 bool cont = true; 253 /* While not at the head of the queue */ 254 while (cont && prev != pfq.begin()) { 255 prev--; 256 /* While at the same level of priority */ |
246 cont = (*prev).priority == (*it).priority; | 257 cont = prev->priority == it->priority; |
247 if (cont) 248 /* update pointer */ 249 it = prev; 250 } 251 DPRINTF(HWPrefetch, "Prefetch queue full, removing lowest priority " | 258 if (cont) 259 /* update pointer */ 260 it = prev; 261 } 262 DPRINTF(HWPrefetch, "Prefetch queue full, removing lowest priority " |
252 "oldest packet, addr: %#x", it->pkt->getAddr()); | 263 "oldest packet, addr: %#x", it->pfInfo.getAddr()); |
253 delete it->pkt; 254 pfq.erase(it); 255 } 256 257 Tick pf_time = curTick() + clockPeriod() * latency; 258 DPRINTF(HWPrefetch, "Prefetch queued. " 259 "addr:%#x priority: %3d tick:%lld.\n", | 264 delete it->pkt; 265 pfq.erase(it); 266 } 267 268 Tick pf_time = curTick() + clockPeriod() * latency; 269 DPRINTF(HWPrefetch, "Prefetch queued. " 270 "addr:%#x priority: %3d tick:%lld.\n", |
260 pf_info.first, pf_info.second, pf_time); | 271 target_addr, priority, pf_time); |
261 262 /* Create the packet and find the spot to insert it */ | 272 273 /* Create the packet and find the spot to insert it */ |
263 DeferredPacket dpp(pf_time, pf_pkt, pf_info.second); | 274 DeferredPacket dpp(new_pfi, pf_time, pf_pkt, priority); |
264 if (pfq.size() == 0) { 265 pfq.emplace_back(dpp); 266 } else { 267 iterator it = pfq.end(); 268 do { 269 --it; 270 } while (it != pfq.begin() && dpp > *it); 271 /* If we reach the head, we have to see if the new element is new head 272 * or not */ 273 if (it == pfq.begin() && dpp <= *it) 274 it++; 275 pfq.insert(it, dpp); 276 } | 275 if (pfq.size() == 0) { 276 pfq.emplace_back(dpp); 277 } else { 278 iterator it = pfq.end(); 279 do { 280 --it; 281 } while (it != pfq.begin() && dpp > *it); 282 /* If we reach the head, we have to see if the new element is new head 283 * or not */ 284 if (it == pfq.begin() && dpp <= *it) 285 it++; 286 pfq.insert(it, dpp); 287 } |
277 278 return pf_pkt; | |
279} | 288} |