gem5  v22.1.0.0
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 
45 #include "cpu/pred/bpred_unit.hh"
46 #include "params/MultiperspectivePerceptron.hh"
47 
48 namespace gem5
49 {
50 
51 namespace 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:
114  bool filtered;
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 
150  struct FilterEntry
151  {
153  bool seenTaken;
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 
225  struct HistorySpec
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;
290  const bool speculative_update;
291 
293  static int xlat[];
295  static int xlat4[];
296 
298  struct ThreadData
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 
487  void addSpec(HistorySpec *spec)
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,
551  : HistorySpec(p1, p2, p3, coeff, size, width, mpp)
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,
646  : HistorySpec(p1, p2, p3, coeff, size, width, mpp)
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,
711  : HistorySpec(p1, p2, p3, coeff, size, width, mpp)
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,
781  : HistorySpec(p1, p2, p3, coeff, size, width, mpp)
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,
809  : HistorySpec(p1, p2, p3, coeff, size, width, mpp)
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 
877  class GHISTMODPATH : public HistorySpec
878  {
879  public:
880  GHISTMODPATH(int p1, int p2, int p3, double coeff, int size, int width,
882  : HistorySpec(p1, p2, p3, coeff, size, width, mpp)
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;
891  std::vector<std::vector<unsigned short int>> &modpath_histories =
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,
915  : HistorySpec(p1, p2, p3, coeff, size, width, mpp)
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,
1004  : HistorySpec(p1, p2, p3, coeff, size, width, mpp)
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.
static unsigned int hash1(unsigned int a)
PC Hash functions.
const unsigned short int pc2
pc of the branch, shifted 2 bits to the right
static unsigned int hash(unsigned int key, unsigned int i)
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
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.
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
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
Definition: sim_object.hh:176
Bitfield< 7 > b
Definition: misc_types.hh:388
Bitfield< 7 > i
Definition: misc_types.hh:67
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< 30, 0 > index
Bitfield< 23 > k
Definition: dt_constants.hh:81
Bitfield< 20, 16 > bi
Definition: types.hh:80
Bitfield< 3 > am
Definition: misc.hh:132
Bitfield< 4 > x
Definition: pagetable.hh:61
Bitfield< 55 > l
Definition: pagetable.hh:54
Bitfield< 0 > v
Definition: pagetable.hh:65
Bitfield< 2 > c
Definition: pagetable.hh:63
Bitfield< 6 > w
Definition: pagetable.hh:59
Bitfield< 51 > t
Definition: pagetable.hh:56
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
std::vector< std::vector< unsigned short int > > modpath_histories
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)

Generated on Wed Dec 21 2022 10:22:31 for gem5 by doxygen 1.9.1