gem5 v23.0.0.1
Loading...
Searching...
No Matches
multiperspective_perceptron.hh
Go to the documentation of this file.
1/*
2 * Copyright 2019 Texas A&M University
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright notice,
8 * this list of conditions and the following disclaimer.
9 *
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 *
14 * 3. Neither the name of the copyright holder nor the names of its
15 * contributors may be used to endorse or promote products derived from this
16 * software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 *
30 * Author: Daniel A. Jiménez
31 * Adapted to gem5 by: Javier Bueno Hedo
32 *
33 */
34
35/*
36 * Multiperspective Perceptron Predictor (by Daniel A. Jiménez)
37 */
38
39#ifndef __CPU_PRED_MULTIPERSPECTIVE_PERCEPTRON_HH__
40#define __CPU_PRED_MULTIPERSPECTIVE_PERCEPTRON_HH__
41
42#include <array>
43#include <vector>
44
46#include "params/MultiperspectivePerceptron.hh"
47
48namespace gem5
49{
50
51namespace branch_prediction
52{
53
55{
56 protected:
61 {
63 const unsigned int pc;
65 const unsigned short int pc2;
67 const unsigned short int hpc;
69 const bool condBranch;
70
74 static inline unsigned int hash1(unsigned int a)
75 {
76 a = (a ^ 0xdeadbeef) + (a<<4);
77 a = a ^ (a>>10);
78 a = a + (a<<7);
79 a = a ^ (a>>13);
80 return a;
81 }
82
83 static inline unsigned int hash2(unsigned int key)
84 {
85 int c2 = 0x27d4eb2d; // a prime or an odd constant
86 key = (key ^ 61) ^ (key >> 16);
87 key = key + (key << 3);
88 key = key ^ (key >> 4);
89 key = key * c2;
90 key = key ^ (key >> 15);
91 return key;
92 }
93
94 static inline unsigned int hash(unsigned int key, unsigned int i)
95 {
96 return hash2(key) * i + hash1(key);
97 }
98
99 static inline unsigned int hashPC(unsigned int pc, int pcshift)
100 {
101 if (pcshift < 0) {
102 return hash(pc, -pcshift);
103 } else if (pcshift < 11) {
104 unsigned int x = pc;
105 x ^= (pc >> pcshift);
106 return x;
107 } else {
108 return pc >> (pcshift-11);
109 }
110 }
111
112 public:
118 int yout;
119
120 MPPBranchInfo(Addr _pc, int pcshift, bool cb) : pc((unsigned int)_pc),
121 pc2(pc >> 2), hpc(hashPC(pc, pcshift)), condBranch(cb),
122 filtered(false), prediction(false), yout(0)
123 { }
124
125 unsigned int getPC() const
126 {
127 return pc;
128 }
129 unsigned short int getPC2() const
130 {
131 return pc2;
132 }
133 unsigned short int getHPC() const
134 {
135 return hpc;
136 }
137 unsigned int getHashFilter(bool last_ghist_bit) const
138 {
139 return last_ghist_bit ^ hpc;
140 }
141 bool isUnconditional() const
142 {
143 return !condBranch;
144 }
145 };
146
151 {
156
157 FilterEntry() : seenTaken(false), seenUntaken(false) {}
158
160 bool alwaysNotTakenSoFar() const {
161 return seenUntaken & !seenTaken;
162 }
164 bool alwaysTakenSoFar() const {
165 return seenTaken & !seenUntaken;
166 }
168 bool neverSeen() const {
169 return !seenTaken && !seenUntaken;
170 }
171 };
172
173
179 {
184
186 unsigned int index(Addr pc) const {
187 return (pc >> 2) % localHistories.size();
188 }
189 public:
190 LocalHistories(int nlocal_histories, int histo_len) :
191 localHistories(nlocal_histories), localHistoryLength(histo_len) {}
192
194 unsigned int operator[](Addr pc) const
195 {
196 return localHistories[index(pc)];
197 }
198
200 void update(Addr pc, bool value)
201 {
202 assert(localHistories.size() > 0);
203 unsigned int &pos = localHistories[index(pc)];
204 pos <<= 1;
205 pos |= value;
206 pos &= ((1<<localHistoryLength)-1);
207 }
208
211 {
212 return localHistoryLength;
213 }
214
216 int getSize() const
217 {
218 return localHistoryLength * localHistories.size();
219 }
220 };
221
226 {
228 const int p1;
230 const int p2;
232 const int p3;
234 const double coeff;
236 const int size;
238 const int width;
241
242 HistorySpec(int _p1, int _p2, int _p3, double _coeff, int _size,
243 int _width, MultiperspectivePerceptron &_mpp) : p1(_p1),
244 p2(_p2), p3(_p3), coeff(_coeff), size(_size), width(_width),
245 mpp(_mpp)
246 {}
247
257 virtual unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t)
258 const = 0;
263 virtual void setBitRequirements() const {}
264 };
265
267 const int blockSize;
268 const int pcshift;
269 const int threshold;
270 const int bias0;
271 const int bias1;
272 const int biasmostly0;
273 const int biasmostly1;
274 const int nbest;
275 const int tunebits;
276 const int hshift;
277 const unsigned long long int imli_mask1;
278 const unsigned long long int imli_mask4;
279 const unsigned long long int recencypos_mask;
280 const double fudge;
281 const int n_sign_bits;
282 const int pcbit;
283 const int decay;
284 const unsigned int record_mask;
285 const bool hash_taken;
286 const bool tuneonly;
287 const int extra_rounds;
288 const int speed;
289 const int budgetbits;
291
293 static int xlat[];
295 static int xlat4[];
296
299 {
300 ThreadData(int num_filter, int n_local_histories,
301 int local_history_length, int assoc,
303 int path_length, int ghist_length, int block_size,
310
314
315 void updateAcyclic(bool hashed_taken, unsigned int hpc) {
316 for (int i = 0; i < acyclic_histories.size(); i += 1) {
317 if (acyclic_histories[i].size() > 0) {
318 acyclic_histories[i][hpc%(i+2)] = hashed_taken;
319 acyclic2_histories[i][hpc%(i+2)] = hpc;
320 }
321 }
322 }
323
332
333 void insertRecency(unsigned int pc, int assoc) {
334 int i = 0;
335 for (i = 0; i < assoc; i += 1) {
336 if (recency_stack[i] == pc) {
337 break;
338 }
339 }
340 if (i == assoc) {
341 i = assoc-1;
342 recency_stack[i] = pc;
343 }
344 int j;
345 unsigned int b = recency_stack[i];
346 for (j = i; j >= 1; j -= 1) {
348 }
349 recency_stack[0] = b;
350 }
351
354
358 };
360
364
368 int assoc;
373 int theta;
382
384 void insertModhistSpec(int p1, int p2) {
385 int j = insert(modhist_indices, p1);
386 if (modhist_lengths.size() < (j + 1)) {
387 modhist_lengths.resize(j + 1);
388 }
389 if (modhist_lengths[j] < p2 + 1) {
390 modhist_lengths[j] = p2 + 1;
391 }
392 if (p2 >= modghist_length) {
393 modghist_length = p2 + 1;
394 }
395 }
396
398 void insertModpathSpec(int p1, int p2) {
399 int j = insert(modpath_indices, p1);
400 if (modpath_lengths.size() < (j + 1)) {
401 modpath_lengths.resize(j + 1);
402 }
403 if (modpath_lengths[j] < p2 + 1) {
404 modpath_lengths[j] = p2 + 1;
405 }
406 if (p2 >= path_length) {
407 path_length = p2 + 1;
408 }
409 }
410
413 {
414 for (int i = 0; i < v.size(); i += 1) {
415 if (v[i] == x) {
416 return i;
417 }
418 }
419 v.push_back(x);
420 return v.size()-1;
421 }
422
432 void computeBits(int num_filter_entries, int nlocal_histories,
433 int local_history_length, bool ignore_path_size);
434
438 virtual void createSpecs() = 0;
439
448 unsigned int getIndex(ThreadID tid, const MPPBranchInfo &bi,
449 const HistorySpec &spec, int index) const;
457 void findBest(ThreadID tid, std::vector<int> &best_preds) const;
458
467
474 void train(ThreadID tid, MPPBranchInfo &bi, bool taken);
475
484 void satIncDec(bool taken, bool &sign, int &c, int max_weight) const;
485
488 {
489 specs.push_back(spec);
490 }
491
494 class GHIST : public HistorySpec
495 {
496 public:
497 GHIST(int p1, int p2, double coeff, int size, int width,
499 : HistorySpec(p1, p2, 0, coeff, size, width, mpp)
500 {}
501
502 unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const
503 override
504 {
505 return hash(mpp.threadData[tid]->ghist_words, mpp.blockSize, p1,
506 p2);
507 }
508
509 static unsigned int hash(const std::vector<unsigned int> &ghist_words,
510 int block_size, int start_pos, int end_pos)
511 {
512 int a = start_pos;
513 int b = end_pos;
514
515 unsigned int x = 0;
516 // am is the next multiple of block_size after a
517 int am = (((a/block_size)*block_size)+block_size);
518 // bm is the previous multiple of block_size before b
519 int bm = (b/block_size)*block_size;
520
521 // the 0th bit of ghist_words[a/block_size] is the most recent bit.
522 // so the number of bits between a and am is the number to shift
523 // right?
524
525 // start out x as remainder bits from the beginning:
526 // x = [ . . . . . b b b b b ]
527 x += ghist_words[a / block_size] >> (a-am);
528 // add in bits from the middle
529 for (int i=am; i<bm; i+=block_size) {
530 x += ghist_words[i / block_size];
531 }
532 // add in remainder bits from end:
533 // x += [ b b b b b . . . . . ]
534 unsigned int y = ghist_words[bm / block_size] & ((1<<(b - bm))-1);
535 x += y << (block_size - (b - bm));
536 return x;
537 }
538 void setBitRequirements() const override
539 {
540 if (mpp.ghist_length <= p2) {
541 mpp.ghist_length = p2 + 1;
542 }
543 }
544 };
545
546 class ACYCLIC : public HistorySpec
547 {
548 public:
549 ACYCLIC(int p1, int p2, int p3, double coeff, int size, int width,
552 {}
553
554 unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const
555 override
556 {
557 int a = p1;
558 int shift = p2;
559 int style = p3;
560 std::vector<std::vector<bool>> &acyclic_histories =
561 mpp.threadData[tid]->acyclic_histories;
562 std::vector<std::vector<unsigned int>> &acyclic2_histories =
563 mpp.threadData[tid]->acyclic2_histories;
564
565 unsigned int x = 0;
566 if (style == -1) {
567 unsigned int k = 0;
568 for (int i = 0; i < a + 2; i += 1) {
569 x ^= acyclic_histories[a][i] << k;
570 k += 1;
571 k %= mpp.blockSize;
572 }
573 } else {
574 for (int i = 0; i < a + 2; i += 1) {
575 x <<= shift;
576 x += acyclic2_histories[a][i];
577 }
578 }
579 return x;
580 }
581 void setBitRequirements() const override
582 {
583 if (mpp.acyclic_bits.size() < (p1 + 1)) {
584 mpp.acyclic_bits.resize(p1 + 1);
585 }
586 if (mpp.acyclic_bits[p1].size() < (p1 + 2)) {
587 mpp.acyclic_bits[p1].resize(p1 + 2, std::vector<bool>(2));
588 }
589 for (int j = 0; j < p1 + 2; j += 1) {
590 mpp.acyclic_bits[p1][j][!p3] = true;
591 }
592 }
593 };
594
595 class MODHIST : public HistorySpec
596 {
597 public:
598 MODHIST(int p1, int p2, double coeff, int size, int width,
600 : HistorySpec(p1, p2, 0, coeff, size, width, mpp)
601 {}
602
603 unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const
604 override
605 {
606 int a = p1;
607 int b = p2;
608 std::vector<std::vector<bool>> &mod_histories =
609 mpp.threadData[tid]->mod_histories;
610
611 unsigned int x = 0, k = 0;
612 for (int i = 0; i < b; i += 1) {
613 x ^= mod_histories[a][i] << k;
614 k += 1;
615 k %= mpp.blockSize;
616 }
617 return x;
618 }
619 void setBitRequirements() const override
620 {
622 }
623 };
624
625 class BIAS : public HistorySpec
626 {
627 public:
628 BIAS(double coeff, int size, int width,
630 : HistorySpec(0, 0, 0, coeff, size, width, mpp)
631 {}
632
633 unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const
634 override
635 {
636 return 0;
637 }
638 };
639
640
641 class RECENCY : public HistorySpec
642 {
643 public:
644 RECENCY(int p1, int p2, int p3, double coeff, int size, int width,
647 {}
648
649 unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const
650 override
651 {
652 int depth = p1;
653 int shift = p2;
654 int style = p3;
655 std::vector<unsigned int short> &recency_stack =
656 mpp.threadData[tid]->recency_stack;
657
658 if (style == -1) {
659 unsigned int x = 0;
660 for (int i = 0; i < depth; i += 1) {
661 x <<= shift;
662 x += recency_stack[i];
663 }
664 return x;
665 } else {
666 unsigned int x = 0, k = 0;
667 for (int i = 0; i < depth; i += 1) {
668 x ^= (!!(recency_stack[i] & (1 << shift))) << k;
669 k += 1;
670 k %= mpp.blockSize;
671 }
672 return x;
673 }
674 }
675 void setBitRequirements() const override
676 {
677 if (mpp.assoc < p1) {
678 mpp.assoc = p1;
679 }
680 mpp.doing_recency = true;
681 }
682 };
683
684 class IMLI : public HistorySpec
685 {
686 public:
687 IMLI(int p1, double coeff, int size, int width,
689 : HistorySpec(p1, 0, 0, coeff, size, width, mpp)
690 {}
691
692 unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const
693 override
694 {
695 assert(p1 >= 1);
696 assert(p1 <= 4);
697 return mpp.threadData[tid]->imli_counter[p1-1];
698 }
699
700 void setBitRequirements() const override
701 {
702 mpp.imli_counter_bits[p1 - 1] = 32;
703 }
704 };
705
706 class PATH : public HistorySpec
707 {
708 public:
709 PATH(int p1, int p2, int p3, double coeff, int size, int width,
712 {}
713
714 unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const
715 override
716 {
717 int depth = p1;
718 int shift = p2;
719 int style = p3;
720 std::vector<unsigned short int> &path_history =
721 mpp.threadData[tid]->path_history;
722
723 if (style == -1) {
724 unsigned int x = 0;
725 for (int i = 0; i < depth; i += 1) {
726 x <<= shift;
727 x += path_history[i];
728 }
729 return x;
730 } else {
731 unsigned int x = 0;
732 int bm = (depth / mpp.blockSize) * mpp.blockSize;
733 for (int i = 0; i < bm; i += mpp.blockSize) {
734 for (int j = 0; j < mpp.blockSize; j += 1) {
735 x ^= (!!(path_history[i + j] & (1 << shift))) << j;
736 }
737 }
738 int k = 0;
739 for (int i = bm; i < depth; i += 1) {
740 x ^= (!!(path_history[i] & (1 << shift))) << k++;
741 }
742 return x;
743 }
744 }
745 void setBitRequirements() const override
746 {
747 if (mpp.path_length <= p1) {
748 mpp.path_length = p1 + 1;
749 }
750 }
751 };
752
753 class LOCAL : public HistorySpec
754 {
755 public:
756 LOCAL(int p1, double coeff, int size, int width,
758 : HistorySpec(p1, 0, 0, coeff, size, width, mpp)
759 {}
760
761 unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const
762 override
763 {
764 unsigned int x = mpp.threadData[tid]->localHistories[pc];
765 if (p1 != -1) {
766 x &= ((1 << p1) - 1);
767 }
768 return x;
769 }
770 void setBitRequirements() const override
771 {
772 mpp.doing_local = true;
773 }
774 };
775
776 class MODPATH : public HistorySpec
777 {
778 public:
779 MODPATH(int p1, int p2, int p3, double coeff, int size, int width,
782 {}
783
784 unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const
785 override
786 {
787 int a = p1;
788 int depth = p2;
789 int shift = p3;
790
791 unsigned int x = 0;
792 for (int i=0; i<depth; i += 1) {
793 x <<= shift;
794 x += mpp.threadData[tid]->modpath_histories[a][i];
795 }
796 return x;
797 }
798 void setBitRequirements() const override
799 {
801 }
802 };
803
804 class GHISTPATH : public HistorySpec
805 {
806 public:
807 GHISTPATH(int p1, int p2, int p3, double coeff, int size, int width,
810 {}
811
812 unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const
813 override
814 {
815 int depth = p1;
816 int shift = p2;
817 int style = p3;
818 std::vector<unsigned int> &ghist_words =
819 mpp.threadData[tid]->ghist_words;
820 std::vector<unsigned short int> &path_history =
821 mpp.threadData[tid]->path_history;
822
823 if (style == -1) {
824 unsigned int x = 0;
825 int bm = (depth / mpp.blockSize) * mpp.blockSize;
826 unsigned int w;
827 for (int i = 0; i < bm; i += mpp.blockSize) {
828 w = ghist_words[i / mpp.blockSize];
829 for (int j = 0; j < mpp.blockSize; j += 1) {
830 x <<= shift;
831 x += (path_history[i + j] << 1) | (w & 1);
832 w >>= 1;
833 }
834 }
835 w = ghist_words[bm / mpp.blockSize];
836 for (int i = bm; i < depth; i += 1) {
837 x <<= shift;
838 x += (path_history[i] << 1) | (w & 1);
839 w >>= 1;
840 }
841 return x;
842 } else {
843 unsigned int x = 0;
844 int bm = (depth / mpp.blockSize) * mpp.blockSize;
845 unsigned int w = 0;
846 for (int i = 0; i < bm; i += mpp.blockSize) {
847 w = ghist_words[i / mpp.blockSize];
848 for (int j = 0; j < mpp.blockSize; j += 1) {
849 x ^= (!!(path_history[i + j] & (1 << shift))) << j;
850 x ^= (w & 1) << j;
851 w >>= 1;
852 }
853 }
854 w = ghist_words[bm/mpp.blockSize];
855 int k = 0;
856 for (int i = bm; i < depth; i += 1) {
857 x ^= (!!(path_history[i] & (1 << shift))) << k;
858 x ^= (w & 1) << k;
859 w >>= 1;
860 k += 1;
861 }
862 return x;
863 }
864 }
865
866 void setBitRequirements() const override
867 {
868 if (mpp.ghist_length <= p1) {
869 mpp.ghist_length = p1 + 1;
870 }
871 if (mpp.path_length <= p1) {
872 mpp.path_length = p1 + 1;
873 }
874 }
875 };
876
878 {
879 public:
880 GHISTMODPATH(int p1, int p2, int p3, double coeff, int size, int width,
883 {}
884
885 unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const
886 override
887 {
888 int a = p1;
889 int depth = p2;
890 int shift = p3;
892 mpp.threadData[tid]->modpath_histories;
893 std::vector<std::vector<bool>> &mod_histories =
894 mpp.threadData[tid]->mod_histories;
895
896 unsigned int x = 0;
897 for (int i = 0; i < depth; i += 1) {
898 x <<= shift;
899 x += (modpath_histories[a][i] << 1) | mod_histories[a][i];
900 }
901 return x;
902 }
903 void setBitRequirements() const override
904 {
907 }
908 };
909
910 class BLURRYPATH : public HistorySpec
911 {
912 public:
913 BLURRYPATH(int p1, int p2, int p3, double coeff, int size, int width,
916 {}
917
918 unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const
919 override
920 {
921 int scale = p1;
922 int depth = p2;
923 int shiftdelta = p3;
924
925 if (shiftdelta == -1) shiftdelta = 0;
926 int sdint = shiftdelta >> 2;
927 int sdfrac = shiftdelta & 3;
928 unsigned int x = 0;
929 int shift = 0;
930 int count = 0;
931 for (int i = 0; i < depth; i += 1) {
932 x += mpp.threadData[tid]->blurrypath_histories[scale][i] >>
933 shift;
934 count += 1;
935 if (count == sdfrac) {
936 shift += sdint;
937 count = 0;
938 }
939 }
940 return x;
941
942 }
943 void setBitRequirements() const override
944 {
945 if (mpp.blurrypath_bits.size() < (p1 + 1)) {
946 mpp.blurrypath_bits.resize(p1 + 1);
947 }
948 if (mpp.blurrypath_bits[p1].size() < p2) {
949 mpp.blurrypath_bits[p1].resize(p2);
950 }
951 for (int j = 0; j < p2; j += 1) {
952 mpp.blurrypath_bits[p1][j] = 32 - p1;
953 }
954 }
955 };
956
957 class RECENCYPOS : public HistorySpec
958 {
959 public:
960 RECENCYPOS(int p1, double coeff, int size, int width,
962 : HistorySpec(p1, 0, 0, coeff, size, width, mpp)
963 {}
964
965 unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const
966 override
967 {
968 return hash(mpp.threadData[tid]->recency_stack, mpp.table_sizes,
969 pc2, p1, t);
970 }
971
972 static unsigned int hash(
973 const std::vector<unsigned int short> &recency_stack,
974 const std::vector<int> &table_sizes, unsigned short int pc, int l,
975 int t)
976 {
977 // search for the PC
978
979 for (int i = 0; i < l; i += 1) {
980 if (recency_stack[i] == pc) {
981 return i * table_sizes[t] / l;
982 }
983 }
984
985 // return last index in table on a miss
986
987 return table_sizes[t] - 1;
988 }
989
990 void setBitRequirements() const override
991 {
992 if (mpp.assoc < p1) {
993 mpp.assoc = p1;
994 }
995 mpp.doing_recency = true;
996 }
997 };
998
999 class SGHISTPATH : public HistorySpec
1000 {
1001 public:
1002 SGHISTPATH(int p1, int p2, int p3, double coeff, int size, int width,
1005 {}
1006
1007 unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const
1008 override
1009 {
1010 int a = p1;
1011 int b = p2;
1012 int shift = p3;
1013 std::vector<unsigned int> &ghist_words =
1014 mpp.threadData[tid]->ghist_words;
1015 std::vector<unsigned short int> &path_history =
1016 mpp.threadData[tid]->path_history;
1017
1018 unsigned int x = 0;
1019 int bm = (b / mpp.blockSize) * mpp.blockSize;
1020 unsigned int w;
1021 for (int i = a; i < bm; i += mpp.blockSize) {
1022 w = ghist_words[i / mpp.blockSize];
1023 for (int j = 0; j < mpp.blockSize; j += 1) {
1024 x <<= shift;
1025 x += (path_history[i+j] << 1) | (w & 1);
1026 w >>= 1;
1027 }
1028 }
1029 w = ghist_words[bm / mpp.blockSize];
1030 for (int i = bm; i < b; i += 1) {
1031 x <<= shift;
1032 x += (path_history[i] << 1) | (w & 1);
1033 w >>= 1;
1034 }
1035 return x;
1036 }
1037 };
1038
1039 public:
1040 MultiperspectivePerceptron(const MultiperspectivePerceptronParams &params);
1041
1047 void setExtraBits(int bits);
1048
1049 void init() override;
1050
1051 void uncondBranch(ThreadID tid, Addr pc, void * &bp_history) override;
1052 void squash(ThreadID tid, void *bp_history) override;
1053 bool lookup(ThreadID tid, Addr instPC, void * &bp_history) override;
1054 void update(ThreadID tid, Addr instPC, bool taken,
1055 void *bp_history, bool squashed,
1056 const StaticInstPtr & inst,
1057 Addr corrTarget) override;
1058 void btbUpdate(ThreadID tid, Addr branch_addr, void* &bp_history) override;
1059};
1060
1061} // namespace branch_prediction
1062} // namespace gem5
1063
1064#endif//__CPU_PRED_MULTIPERSPECTIVE_PERCEPTRON_HH__
Basically a wrapper class to hold both the branch predictor and the BTB.
Definition bpred_unit.hh:69
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...
bool lookup(ThreadID tid, Addr instPC, void *&bp_history) override
Looks up a given PC in the BP to see if it is taken or not taken.
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...
void btbUpdate(ThreadID tid, Addr branch_addr, void *&bp_history) override
If a branch is not taken, because the BTB address is invalid or missing, this function sets the appro...
static int xlat[]
Transfer function for 6-width tables.
bool doing_local
runtime values and data used to count the size in bits
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.
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 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.
void uncondBranch(ThreadID tid, Addr pc, void *&bp_history) override
std::vector< HistorySpec * > specs
Predictor tables.
void update(ThreadID tid, Addr instPC, bool taken, void *bp_history, bool squashed, const StaticInstPtr &inst, Addr corrTarget) override
Updates the BP with taken/not taken information.
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:76
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< 24 > j
Definition misc_types.hh:57
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
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
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.
std::vector< std::vector< std::array< bool, 2 > > > sign_bits

Generated on Mon Jul 10 2023 15:32:01 for gem5 by doxygen 1.9.7