gem5 v24.0.0.0
Loading...
Searching...
No Matches
multiperspective_perceptron.hh
Go to the documentation of this file.
1/*
2 * Copyright (c) 2022-2023 The University of Edinburgh
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
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Copyright 2019 Texas A&M University
15 *
16 * Redistribution and use in source and binary forms, with or without
17 * modification, are permitted provided that the following conditions are met:
18 *
19 * 1. Redistributions of source code must retain the above copyright notice,
20 * this list of conditions and the following disclaimer.
21 *
22 * 2. Redistributions in binary form must reproduce the above copyright notice,
23 * this list of conditions and the following disclaimer in the documentation
24 * and/or other materials provided with the distribution.
25 *
26 * 3. Neither the name of the copyright holder nor the names of its
27 * contributors may be used to endorse or promote products derived from this
28 * software without specific prior written permission.
29 *
30 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
31 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
32 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
33 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
34 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
35 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
36 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
37 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
38 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
39 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
40 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41 *
42 * Author: Daniel A. Jiménez
43 * Adapted to gem5 by: Javier Bueno Hedo
44 *
45 */
46
47/*
48 * Multiperspective Perceptron Predictor (by Daniel A. Jiménez)
49 */
50
51#ifndef __CPU_PRED_MULTIPERSPECTIVE_PERCEPTRON_HH__
52#define __CPU_PRED_MULTIPERSPECTIVE_PERCEPTRON_HH__
53
54#include <array>
55#include <vector>
56
58#include "params/MultiperspectivePerceptron.hh"
59
60namespace gem5
61{
62
63namespace branch_prediction
64{
65
67{
68 protected:
73 {
75 const unsigned int pc;
77 const unsigned short int pc2;
79 const unsigned short int hpc;
81 const bool condBranch;
82
86 static inline unsigned int hash1(unsigned int a)
87 {
88 a = (a ^ 0xdeadbeef) + (a<<4);
89 a = a ^ (a>>10);
90 a = a + (a<<7);
91 a = a ^ (a>>13);
92 return a;
93 }
94
95 static inline unsigned int hash2(unsigned int key)
96 {
97 int c2 = 0x27d4eb2d; // a prime or an odd constant
98 key = (key ^ 61) ^ (key >> 16);
99 key = key + (key << 3);
100 key = key ^ (key >> 4);
101 key = key * c2;
102 key = key ^ (key >> 15);
103 return key;
104 }
105
106 static inline unsigned int hash(unsigned int key, unsigned int i)
107 {
108 return hash2(key) * i + hash1(key);
109 }
110
111 static inline unsigned int hashPC(unsigned int pc, int pcshift)
112 {
113 if (pcshift < 0) {
114 return hash(pc, -pcshift);
115 } else if (pcshift < 11) {
116 unsigned int x = pc;
117 x ^= (pc >> pcshift);
118 return x;
119 } else {
120 return pc >> (pcshift-11);
121 }
122 }
123
124 public:
130 int yout;
131
132 MPPBranchInfo(Addr _pc, int pcshift, bool cb) : pc((unsigned int)_pc),
133 pc2(pc >> 2), hpc(hashPC(pc, pcshift)), condBranch(cb),
134 filtered(false), prediction(false), yout(0)
135 { }
136
137 unsigned int getPC() const
138 {
139 return pc;
140 }
141 unsigned short int getPC2() const
142 {
143 return pc2;
144 }
145 unsigned short int getHPC() const
146 {
147 return hpc;
148 }
149 unsigned int getHashFilter(bool last_ghist_bit) const
150 {
151 return last_ghist_bit ^ hpc;
152 }
153 bool isUnconditional() const
154 {
155 return !condBranch;
156 }
157 };
158
163 {
168
169 FilterEntry() : seenTaken(false), seenUntaken(false) {}
170
172 bool alwaysNotTakenSoFar() const {
173 return seenUntaken & !seenTaken;
174 }
176 bool alwaysTakenSoFar() const {
177 return seenTaken & !seenUntaken;
178 }
180 bool neverSeen() const {
181 return !seenTaken && !seenUntaken;
182 }
183 };
184
185
191 {
196
198 unsigned int index(Addr pc) const {
199 return (pc >> 2) % localHistories.size();
200 }
201 public:
202 LocalHistories(int nlocal_histories, int histo_len) :
203 localHistories(nlocal_histories), localHistoryLength(histo_len) {}
204
206 unsigned int operator[](Addr pc) const
207 {
208 return localHistories[index(pc)];
209 }
210
212 void update(Addr pc, bool value)
213 {
214 assert(localHistories.size() > 0);
215 unsigned int &pos = localHistories[index(pc)];
216 pos <<= 1;
217 pos |= value;
218 pos &= ((1<<localHistoryLength)-1);
219 }
220
223 {
224 return localHistoryLength;
225 }
226
228 int getSize() const
229 {
230 return localHistoryLength * localHistories.size();
231 }
232 };
233
238 {
240 const int p1;
242 const int p2;
244 const int p3;
246 const double coeff;
248 const int size;
250 const int width;
253
254 HistorySpec(int _p1, int _p2, int _p3, double _coeff, int _size,
255 int _width, MultiperspectivePerceptron &_mpp) : p1(_p1),
256 p2(_p2), p3(_p3), coeff(_coeff), size(_size), width(_width),
257 mpp(_mpp)
258 {}
259
269 virtual unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t)
270 const = 0;
275 virtual void setBitRequirements() const {}
276 };
277
279 const int blockSize;
280 const int pcshift;
281 const int threshold;
282 const int bias0;
283 const int bias1;
284 const int biasmostly0;
285 const int biasmostly1;
286 const int nbest;
287 const int tunebits;
288 const int hshift;
289 const unsigned long long int imli_mask1;
290 const unsigned long long int imli_mask4;
291 const unsigned long long int recencypos_mask;
292 const double fudge;
293 const int n_sign_bits;
294 const int pcbit;
295 const int decay;
296 const unsigned int record_mask;
297 const bool hash_taken;
298 const bool tuneonly;
299 const int extra_rounds;
300 const int speed;
301 const int budgetbits;
303
305 static int xlat[];
307 static int xlat4[];
308
311 {
312 ThreadData(int num_filter, int n_local_histories,
313 int local_history_length, int assoc,
315 int path_length, int ghist_length, int block_size,
322
326
327 void updateAcyclic(bool hashed_taken, unsigned int hpc) {
328 for (int i = 0; i < acyclic_histories.size(); i += 1) {
329 if (acyclic_histories[i].size() > 0) {
330 acyclic_histories[i][hpc%(i+2)] = hashed_taken;
331 acyclic2_histories[i][hpc%(i+2)] = hpc;
332 }
333 }
334 }
335
344
345 void insertRecency(unsigned int pc, int assoc) {
346 int i = 0;
347 for (i = 0; i < assoc; i += 1) {
348 if (recency_stack[i] == pc) {
349 break;
350 }
351 }
352 if (i == assoc) {
353 i = assoc-1;
354 recency_stack[i] = pc;
355 }
356 int j;
357 unsigned int b = recency_stack[i];
358 for (j = i; j >= 1; j -= 1) {
360 }
361 recency_stack[0] = b;
362 }
363
366
370 };
372
376
380 int assoc;
385 int theta;
394
396 void insertModhistSpec(int p1, int p2) {
397 int j = insert(modhist_indices, p1);
398 if (modhist_lengths.size() < (j + 1)) {
399 modhist_lengths.resize(j + 1);
400 }
401 if (modhist_lengths[j] < p2 + 1) {
402 modhist_lengths[j] = p2 + 1;
403 }
404 if (p2 >= modghist_length) {
405 modghist_length = p2 + 1;
406 }
407 }
408
410 void insertModpathSpec(int p1, int p2) {
411 int j = insert(modpath_indices, p1);
412 if (modpath_lengths.size() < (j + 1)) {
413 modpath_lengths.resize(j + 1);
414 }
415 if (modpath_lengths[j] < p2 + 1) {
416 modpath_lengths[j] = p2 + 1;
417 }
418 if (p2 >= path_length) {
419 path_length = p2 + 1;
420 }
421 }
422
425 {
426 for (int i = 0; i < v.size(); i += 1) {
427 if (v[i] == x) {
428 return i;
429 }
430 }
431 v.push_back(x);
432 return v.size()-1;
433 }
434
444 void computeBits(int num_filter_entries, int nlocal_histories,
445 int local_history_length, bool ignore_path_size);
446
450 virtual void createSpecs() = 0;
451
460 unsigned int getIndex(ThreadID tid, const MPPBranchInfo &bi,
461 const HistorySpec &spec, int index) const;
469 void findBest(ThreadID tid, std::vector<int> &best_preds) const;
470
479
486 void train(ThreadID tid, MPPBranchInfo &bi, bool taken);
487
496 void satIncDec(bool taken, bool &sign, int &c, int max_weight) const;
497
500 {
501 specs.push_back(spec);
502 }
503
506 class GHIST : public HistorySpec
507 {
508 public:
509 GHIST(int p1, int p2, double coeff, int size, int width,
511 : HistorySpec(p1, p2, 0, coeff, size, width, mpp)
512 {}
513
514 unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const
515 override
516 {
517 return hash(mpp.threadData[tid]->ghist_words, mpp.blockSize, p1,
518 p2);
519 }
520
521 static unsigned int hash(const std::vector<unsigned int> &ghist_words,
522 int block_size, int start_pos, int end_pos)
523 {
524 int a = start_pos;
525 int b = end_pos;
526
527 unsigned int x = 0;
528 // am is the next multiple of block_size after a
529 int am = (((a/block_size)*block_size)+block_size);
530 // bm is the previous multiple of block_size before b
531 int bm = (b/block_size)*block_size;
532
533 // the 0th bit of ghist_words[a/block_size] is the most recent bit.
534 // so the number of bits between a and am is the number to shift
535 // right?
536
537 // start out x as remainder bits from the beginning:
538 // x = [ . . . . . b b b b b ]
539 x += ghist_words[a / block_size] >> (a-am);
540 // add in bits from the middle
541 for (int i=am; i<bm; i+=block_size) {
542 x += ghist_words[i / block_size];
543 }
544 // add in remainder bits from end:
545 // x += [ b b b b b . . . . . ]
546 unsigned int y = ghist_words[bm / block_size] & ((1<<(b - bm))-1);
547 x += y << (block_size - (b - bm));
548 return x;
549 }
550 void setBitRequirements() const override
551 {
552 if (mpp.ghist_length <= p2) {
553 mpp.ghist_length = p2 + 1;
554 }
555 }
556 };
557
558 class ACYCLIC : public HistorySpec
559 {
560 public:
561 ACYCLIC(int p1, int p2, int p3, double coeff, int size, int width,
564 {}
565
566 unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const
567 override
568 {
569 int a = p1;
570 int shift = p2;
571 int style = p3;
572 std::vector<std::vector<bool>> &acyclic_histories =
573 mpp.threadData[tid]->acyclic_histories;
574 std::vector<std::vector<unsigned int>> &acyclic2_histories =
575 mpp.threadData[tid]->acyclic2_histories;
576
577 unsigned int x = 0;
578 if (style == -1) {
579 unsigned int k = 0;
580 for (int i = 0; i < a + 2; i += 1) {
581 x ^= acyclic_histories[a][i] << k;
582 k += 1;
583 k %= mpp.blockSize;
584 }
585 } else {
586 for (int i = 0; i < a + 2; i += 1) {
587 x <<= shift;
588 x += acyclic2_histories[a][i];
589 }
590 }
591 return x;
592 }
593 void setBitRequirements() const override
594 {
595 if (mpp.acyclic_bits.size() < (p1 + 1)) {
596 mpp.acyclic_bits.resize(p1 + 1);
597 }
598 if (mpp.acyclic_bits[p1].size() < (p1 + 2)) {
599 mpp.acyclic_bits[p1].resize(p1 + 2, std::vector<bool>(2));
600 }
601 for (int j = 0; j < p1 + 2; j += 1) {
602 mpp.acyclic_bits[p1][j][!p3] = true;
603 }
604 }
605 };
606
607 class MODHIST : public HistorySpec
608 {
609 public:
610 MODHIST(int p1, int p2, double coeff, int size, int width,
612 : HistorySpec(p1, p2, 0, coeff, size, width, mpp)
613 {}
614
615 unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const
616 override
617 {
618 int a = p1;
619 int b = p2;
620 std::vector<std::vector<bool>> &mod_histories =
621 mpp.threadData[tid]->mod_histories;
622
623 unsigned int x = 0, k = 0;
624 for (int i = 0; i < b; i += 1) {
625 x ^= mod_histories[a][i] << k;
626 k += 1;
627 k %= mpp.blockSize;
628 }
629 return x;
630 }
631 void setBitRequirements() const override
632 {
634 }
635 };
636
637 class BIAS : public HistorySpec
638 {
639 public:
640 BIAS(double coeff, int size, int width,
642 : HistorySpec(0, 0, 0, coeff, size, width, mpp)
643 {}
644
645 unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const
646 override
647 {
648 return 0;
649 }
650 };
651
652
653 class RECENCY : public HistorySpec
654 {
655 public:
656 RECENCY(int p1, int p2, int p3, double coeff, int size, int width,
659 {}
660
661 unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const
662 override
663 {
664 int depth = p1;
665 int shift = p2;
666 int style = p3;
667 std::vector<unsigned int short> &recency_stack =
668 mpp.threadData[tid]->recency_stack;
669
670 if (style == -1) {
671 unsigned int x = 0;
672 for (int i = 0; i < depth; i += 1) {
673 x <<= shift;
674 x += recency_stack[i];
675 }
676 return x;
677 } else {
678 unsigned int x = 0, k = 0;
679 for (int i = 0; i < depth; i += 1) {
680 x ^= (!!(recency_stack[i] & (1 << shift))) << k;
681 k += 1;
682 k %= mpp.blockSize;
683 }
684 return x;
685 }
686 }
687 void setBitRequirements() const override
688 {
689 if (mpp.assoc < p1) {
690 mpp.assoc = p1;
691 }
692 mpp.doing_recency = true;
693 }
694 };
695
696 class IMLI : public HistorySpec
697 {
698 public:
699 IMLI(int p1, double coeff, int size, int width,
701 : HistorySpec(p1, 0, 0, coeff, size, width, mpp)
702 {}
703
704 unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const
705 override
706 {
707 assert(p1 >= 1);
708 assert(p1 <= 4);
709 return mpp.threadData[tid]->imli_counter[p1-1];
710 }
711
712 void setBitRequirements() const override
713 {
714 mpp.imli_counter_bits[p1 - 1] = 32;
715 }
716 };
717
718 class PATH : public HistorySpec
719 {
720 public:
721 PATH(int p1, int p2, int p3, double coeff, int size, int width,
724 {}
725
726 unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const
727 override
728 {
729 int depth = p1;
730 int shift = p2;
731 int style = p3;
732 std::vector<unsigned short int> &path_history =
733 mpp.threadData[tid]->path_history;
734
735 if (style == -1) {
736 unsigned int x = 0;
737 for (int i = 0; i < depth; i += 1) {
738 x <<= shift;
739 x += path_history[i];
740 }
741 return x;
742 } else {
743 unsigned int x = 0;
744 int bm = (depth / mpp.blockSize) * mpp.blockSize;
745 for (int i = 0; i < bm; i += mpp.blockSize) {
746 for (int j = 0; j < mpp.blockSize; j += 1) {
747 x ^= (!!(path_history[i + j] & (1 << shift))) << j;
748 }
749 }
750 int k = 0;
751 for (int i = bm; i < depth; i += 1) {
752 x ^= (!!(path_history[i] & (1 << shift))) << k++;
753 }
754 return x;
755 }
756 }
757 void setBitRequirements() const override
758 {
759 if (mpp.path_length <= p1) {
760 mpp.path_length = p1 + 1;
761 }
762 }
763 };
764
765 class LOCAL : public HistorySpec
766 {
767 public:
768 LOCAL(int p1, double coeff, int size, int width,
770 : HistorySpec(p1, 0, 0, coeff, size, width, mpp)
771 {}
772
773 unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const
774 override
775 {
776 unsigned int x = mpp.threadData[tid]->localHistories[pc];
777 if (p1 != -1) {
778 x &= ((1 << p1) - 1);
779 }
780 return x;
781 }
782 void setBitRequirements() const override
783 {
784 mpp.doing_local = true;
785 }
786 };
787
788 class MODPATH : public HistorySpec
789 {
790 public:
791 MODPATH(int p1, int p2, int p3, double coeff, int size, int width,
794 {}
795
796 unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const
797 override
798 {
799 int a = p1;
800 int depth = p2;
801 int shift = p3;
802
803 unsigned int x = 0;
804 for (int i=0; i<depth; i += 1) {
805 x <<= shift;
806 x += mpp.threadData[tid]->modpath_histories[a][i];
807 }
808 return x;
809 }
810 void setBitRequirements() const override
811 {
813 }
814 };
815
816 class GHISTPATH : public HistorySpec
817 {
818 public:
819 GHISTPATH(int p1, int p2, int p3, double coeff, int size, int width,
822 {}
823
824 unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const
825 override
826 {
827 int depth = p1;
828 int shift = p2;
829 int style = p3;
830 std::vector<unsigned int> &ghist_words =
831 mpp.threadData[tid]->ghist_words;
832 std::vector<unsigned short int> &path_history =
833 mpp.threadData[tid]->path_history;
834
835 if (style == -1) {
836 unsigned int x = 0;
837 int bm = (depth / mpp.blockSize) * mpp.blockSize;
838 unsigned int w;
839 for (int i = 0; i < bm; i += mpp.blockSize) {
840 w = ghist_words[i / mpp.blockSize];
841 for (int j = 0; j < mpp.blockSize; j += 1) {
842 x <<= shift;
843 x += (path_history[i + j] << 1) | (w & 1);
844 w >>= 1;
845 }
846 }
847 w = ghist_words[bm / mpp.blockSize];
848 for (int i = bm; i < depth; i += 1) {
849 x <<= shift;
850 x += (path_history[i] << 1) | (w & 1);
851 w >>= 1;
852 }
853 return x;
854 } else {
855 unsigned int x = 0;
856 int bm = (depth / mpp.blockSize) * mpp.blockSize;
857 unsigned int w = 0;
858 for (int i = 0; i < bm; i += mpp.blockSize) {
859 w = ghist_words[i / mpp.blockSize];
860 for (int j = 0; j < mpp.blockSize; j += 1) {
861 x ^= (!!(path_history[i + j] & (1 << shift))) << j;
862 x ^= (w & 1) << j;
863 w >>= 1;
864 }
865 }
866 w = ghist_words[bm/mpp.blockSize];
867 int k = 0;
868 for (int i = bm; i < depth; i += 1) {
869 x ^= (!!(path_history[i] & (1 << shift))) << k;
870 x ^= (w & 1) << k;
871 w >>= 1;
872 k += 1;
873 }
874 return x;
875 }
876 }
877
878 void setBitRequirements() const override
879 {
880 if (mpp.ghist_length <= p1) {
881 mpp.ghist_length = p1 + 1;
882 }
883 if (mpp.path_length <= p1) {
884 mpp.path_length = p1 + 1;
885 }
886 }
887 };
888
890 {
891 public:
892 GHISTMODPATH(int p1, int p2, int p3, double coeff, int size, int width,
895 {}
896
897 unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const
898 override
899 {
900 int a = p1;
901 int depth = p2;
902 int shift = p3;
904 mpp.threadData[tid]->modpath_histories;
905 std::vector<std::vector<bool>> &mod_histories =
906 mpp.threadData[tid]->mod_histories;
907
908 unsigned int x = 0;
909 for (int i = 0; i < depth; i += 1) {
910 x <<= shift;
911 x += (modpath_histories[a][i] << 1) | mod_histories[a][i];
912 }
913 return x;
914 }
915 void setBitRequirements() const override
916 {
919 }
920 };
921
922 class BLURRYPATH : public HistorySpec
923 {
924 public:
925 BLURRYPATH(int p1, int p2, int p3, double coeff, int size, int width,
928 {}
929
930 unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const
931 override
932 {
933 int scale = p1;
934 int depth = p2;
935 int shiftdelta = p3;
936
937 if (shiftdelta == -1) shiftdelta = 0;
938 int sdint = shiftdelta >> 2;
939 int sdfrac = shiftdelta & 3;
940 unsigned int x = 0;
941 int shift = 0;
942 int count = 0;
943 for (int i = 0; i < depth; i += 1) {
944 x += mpp.threadData[tid]->blurrypath_histories[scale][i] >>
945 shift;
946 count += 1;
947 if (count == sdfrac) {
948 shift += sdint;
949 count = 0;
950 }
951 }
952 return x;
953
954 }
955 void setBitRequirements() const override
956 {
957 if (mpp.blurrypath_bits.size() < (p1 + 1)) {
958 mpp.blurrypath_bits.resize(p1 + 1);
959 }
960 if (mpp.blurrypath_bits[p1].size() < p2) {
961 mpp.blurrypath_bits[p1].resize(p2);
962 }
963 for (int j = 0; j < p2; j += 1) {
964 mpp.blurrypath_bits[p1][j] = 32 - p1;
965 }
966 }
967 };
968
969 class RECENCYPOS : public HistorySpec
970 {
971 public:
972 RECENCYPOS(int p1, double coeff, int size, int width,
974 : HistorySpec(p1, 0, 0, coeff, size, width, mpp)
975 {}
976
977 unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const
978 override
979 {
980 return hash(mpp.threadData[tid]->recency_stack, mpp.table_sizes,
981 pc2, p1, t);
982 }
983
984 static unsigned int hash(
985 const std::vector<unsigned int short> &recency_stack,
986 const std::vector<int> &table_sizes, unsigned short int pc, int l,
987 int t)
988 {
989 // search for the PC
990
991 for (int i = 0; i < l; i += 1) {
992 if (recency_stack[i] == pc) {
993 return i * table_sizes[t] / l;
994 }
995 }
996
997 // return last index in table on a miss
998
999 return table_sizes[t] - 1;
1000 }
1001
1002 void setBitRequirements() const override
1003 {
1004 if (mpp.assoc < p1) {
1005 mpp.assoc = p1;
1006 }
1007 mpp.doing_recency = true;
1008 }
1009 };
1010
1012 {
1013 public:
1014 SGHISTPATH(int p1, int p2, int p3, double coeff, int size, int width,
1017 {}
1018
1019 unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const
1020 override
1021 {
1022 int a = p1;
1023 int b = p2;
1024 int shift = p3;
1025 std::vector<unsigned int> &ghist_words =
1026 mpp.threadData[tid]->ghist_words;
1027 std::vector<unsigned short int> &path_history =
1028 mpp.threadData[tid]->path_history;
1029
1030 unsigned int x = 0;
1031 int bm = (b / mpp.blockSize) * mpp.blockSize;
1032 unsigned int w;
1033 for (int i = a; i < bm; i += mpp.blockSize) {
1034 w = ghist_words[i / mpp.blockSize];
1035 for (int j = 0; j < mpp.blockSize; j += 1) {
1036 x <<= shift;
1037 x += (path_history[i+j] << 1) | (w & 1);
1038 w >>= 1;
1039 }
1040 }
1041 w = ghist_words[bm / mpp.blockSize];
1042 for (int i = bm; i < b; i += 1) {
1043 x <<= shift;
1044 x += (path_history[i] << 1) | (w & 1);
1045 w >>= 1;
1046 }
1047 return x;
1048 }
1049 };
1050
1051 public:
1052 MultiperspectivePerceptron(const MultiperspectivePerceptronParams &params);
1053
1059 void setExtraBits(int bits);
1060
1061 void init() override;
1062
1063 // Base class methods.
1064 bool lookup(ThreadID tid, Addr branch_addr, void* &bp_history) override;
1065 void updateHistories(ThreadID tid, Addr pc, bool uncond, bool taken,
1066 Addr target, void * &bp_history) override;
1067 void update(ThreadID tid, Addr pc, bool taken,
1068 void * &bp_history, bool squashed,
1069 const StaticInstPtr & inst, Addr target) override;
1070 void squash(ThreadID tid, void * &bp_history) override;
1071};
1072
1073} // namespace branch_prediction
1074} // namespace gem5
1075
1076#endif//__CPU_PRED_MULTIPERSPECTIVE_PERCEPTRON_HH__
Basically a wrapper class to hold both the branch predictor and the BTB.
Definition bpred_unit.hh:71
void setBitRequirements() const override
Sets the size requirements of the table, used when initializing to set the proper size of the tables.
ACYCLIC(int p1, int p2, int p3, double coeff, int size, int width, MultiperspectivePerceptron &mpp)
unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const override
Gets the hash to index the table, using the pc of the branch, and the index of the table.
unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const override
Gets the hash to index the table, using the pc of the branch, and the index of the table.
BIAS(double coeff, int size, int width, MultiperspectivePerceptron &mpp)
BLURRYPATH(int p1, int p2, int p3, double coeff, int size, int width, MultiperspectivePerceptron &mpp)
void setBitRequirements() const override
Sets the size requirements of the table, used when initializing to set the proper size of the tables.
unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const override
Gets the hash to index the table, using the pc of the branch, and the index of the table.
void setBitRequirements() const override
Sets the size requirements of the table, used when initializing to set the proper size of the tables.
unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const override
Gets the hash to index the table, using the pc of the branch, and the index of the table.
GHISTMODPATH(int p1, int p2, int p3, double coeff, int size, int width, MultiperspectivePerceptron &mpp)
unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const override
Gets the hash to index the table, using the pc of the branch, and the index of the table.
void setBitRequirements() const override
Sets the size requirements of the table, used when initializing to set the proper size of the tables.
GHISTPATH(int p1, int p2, int p3, double coeff, int size, int width, MultiperspectivePerceptron &mpp)
void setBitRequirements() const override
Sets the size requirements of the table, used when initializing to set the proper size of the tables.
unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const override
Gets the hash to index the table, using the pc of the branch, and the index of the table.
static unsigned int hash(const std::vector< unsigned int > &ghist_words, int block_size, int start_pos, int end_pos)
GHIST(int p1, int p2, double coeff, int size, int width, MultiperspectivePerceptron &mpp)
void setBitRequirements() const override
Sets the size requirements of the table, used when initializing to set the proper size of the tables.
IMLI(int p1, double coeff, int size, int width, MultiperspectivePerceptron &mpp)
unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const override
Gets the hash to index the table, using the pc of the branch, and the index of the table.
LOCAL(int p1, double coeff, int size, int width, MultiperspectivePerceptron &mpp)
unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const override
Gets the hash to index the table, using the pc of the branch, and the index of the table.
void setBitRequirements() const override
Sets the size requirements of the table, used when initializing to set the proper size of the tables.
Local history entries, each enty contains the history of directions taken by a given branch.
int getSize() const
Size in bits required by all history entries.
unsigned int operator[](Addr pc) const
Obtains the local history entry of a given branch.
void update(Addr pc, bool value)
Adds a history bit to the local history entry of a given branch.
int getLocalHistoryLength() const
Returns the number of bits of each local history entry.
unsigned int index(Addr pc) const
Index function given the pc of the branch.
MODHIST(int p1, int p2, double coeff, int size, int width, MultiperspectivePerceptron &mpp)
void setBitRequirements() const override
Sets the size requirements of the table, used when initializing to set the proper size of the tables.
unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const override
Gets the hash to index the table, using the pc of the branch, and the index of the table.
MODPATH(int p1, int p2, int p3, double coeff, int size, int width, MultiperspectivePerceptron &mpp)
void setBitRequirements() const override
Sets the size requirements of the table, used when initializing to set the proper size of the tables.
unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const override
Gets the hash to index the table, using the pc of the branch, and the index of the table.
bool filtered
Whether this branch has been filtered by the prefetcher.
const unsigned short int pc2
pc of the branch, shifted 2 bits to the right
unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const override
Gets the hash to index the table, using the pc of the branch, and the index of the table.
PATH(int p1, int p2, int p3, double coeff, int size, int width, MultiperspectivePerceptron &mpp)
void setBitRequirements() const override
Sets the size requirements of the table, used when initializing to set the proper size of the tables.
void setBitRequirements() const override
Sets the size requirements of the table, used when initializing to set the proper size of the tables.
static unsigned int hash(const std::vector< unsigned int short > &recency_stack, const std::vector< int > &table_sizes, unsigned short int pc, int l, int t)
unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const override
Gets the hash to index the table, using the pc of the branch, and the index of the table.
RECENCYPOS(int p1, double coeff, int size, int width, MultiperspectivePerceptron &mpp)
unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const override
Gets the hash to index the table, using the pc of the branch, and the index of the table.
void setBitRequirements() const override
Sets the size requirements of the table, used when initializing to set the proper size of the tables.
RECENCY(int p1, int p2, int p3, double coeff, int size, int width, MultiperspectivePerceptron &mpp)
SGHISTPATH(int p1, int p2, int p3, double coeff, int size, int width, MultiperspectivePerceptron &mpp)
unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const override
Gets the hash to index the table, using the pc of the branch, and the index of the table.
void insertModhistSpec(int p1, int p2)
Auxiliary function for MODHIST and GHISTMODPATH features.
void insertModpathSpec(int p1, int p2)
Auxiliary function for MODPATH and GHISTMODPATH features.
std::vector< std::vector< std::vector< bool > > > acyclic_bits
int computeOutput(ThreadID tid, MPPBranchInfo &bi)
Computes the output of the predictor for a given branch and the resulting best value in case the pred...
void addSpec(HistorySpec *spec)
Add a table spec to the prefetcher.
int insert(std::vector< int > &v, int x)
Auxiliary function used by insertModhistSpec and insertModpathSpec.
void findBest(ThreadID tid, std::vector< int > &best_preds) const
Finds the best subset of features to use in case of a low-confidence branch, returns the result as an...
static int xlat[]
Transfer function for 6-width tables.
bool doing_local
runtime values and data used to count the size in bits
MultiperspectivePerceptron(const MultiperspectivePerceptronParams &params)
unsigned int getIndex(ThreadID tid, const MPPBranchInfo &bi, const HistorySpec &spec, int index) const
Get the position index of a predictor table.
virtual void createSpecs()=0
Creates the tables of the predictor.
void satIncDec(bool taken, bool &sign, int &c, int max_weight) const
Auxiliary function to increase a table counter depending on the direction of the branch.
bool lookup(ThreadID tid, Addr branch_addr, void *&bp_history) override
Looks up a given conditional branch PC of in the BP to see if it is taken or not taken.
void computeBits(int num_filter_entries, int nlocal_histories, int local_history_length, bool ignore_path_size)
Computes the size in bits of the structures needed to keep track of the history and the predictor tab...
static int xlat4[]
Transfer function for 5-width tables.
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
void update(ThreadID tid, Addr pc, bool taken, void *&bp_history, bool squashed, const StaticInstPtr &inst, Addr target) override
Updates the BP with taken/not taken information.
void train(ThreadID tid, MPPBranchInfo &bi, bool taken)
Trains the branch predictor with the given branch and direction.
void setExtraBits(int bits)
Sets the starting number of storage bits to compute the number of table entries.
std::vector< HistorySpec * > specs
Predictor tables.
void updateHistories(ThreadID tid, Addr pc, bool uncond, bool taken, Addr target, void *&bp_history) override
Ones done with the prediction this function updates the path and global history.
void squash(ThreadID tid, void *&bp_history) override
STL vector class.
Definition stl.hh:37
constexpr T bits(T val, unsigned first, unsigned last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it.
Definition bitfield.hh:79
const Params & params() const
Bitfield< 28 > v
Definition misc_types.hh:54
Bitfield< 5 > t
Definition misc_types.hh:71
Bitfield< 7 > b
Bitfield< 7 > i
Definition misc_types.hh:67
Bitfield< 29 > c
Definition misc_types.hh:53
Bitfield< 8 > a
Definition misc_types.hh:66
Bitfield< 6, 5 > shift
Definition types.hh:117
Bitfield< 4 > pc
Bitfield< 5 > l
Bitfield< 30, 0 > index
Bitfield< 23 > k
Bitfield< 6 > c2
Bitfield< 0 > w
Bitfield< 20, 16 > bi
Definition types.hh:80
Bitfield< 3 > x
Definition pagetable.hh:73
Bitfield< 3 > am
Definition misc.hh:132
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Definition binary32.hh:36
int16_t ThreadID
Thread index/ID type.
Definition types.hh:235
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition types.hh:147
bool alwaysTakenSoFar() const
Whether this branch has always been observed as taken.
bool neverSeen() const
Whether this branch has been observed before.
bool alwaysNotTakenSoFar() const
Whether this branch has always been observed as not taken.
const int size
Pre-assigned size in bits assigned to this feature.
virtual unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const =0
Gets the hash to index the table, using the pc of the branch, and the index of the table.
MultiperspectivePerceptron & mpp
Reference to the branch predictor class.
virtual void setBitRequirements() const
Sets the size requirements of the table, used when initializing to set the proper size of the tables.
HistorySpec(int _p1, int _p2, int _p3, double _coeff, int _size, int _width, MultiperspectivePerceptron &_mpp)
const double coeff
Coefficient of the feature, models the accuracy of the feature.
ThreadData(int num_filter, int n_local_histories, int local_history_length, int assoc, const std::vector< std::vector< int > > &blurrypath_bits, int path_length, int ghist_length, int block_size, const std::vector< std::vector< std::vector< bool > > > &acyclic_bits, const std::vector< int > &modhist_indices, const std::vector< int > &modhist_lengths, const std::vector< int > &modpath_indices, const std::vector< int > &modpath_lengths, const std::vector< int > &table_sizes, int n_sign_bits)
std::vector< std::vector< std::array< bool, 2 > > > sign_bits

Generated on Tue Jun 18 2024 16:24:02 for gem5 by doxygen 1.11.0