gem5  v19.0.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 
49 {
50  protected:
54  class MPPBranchInfo {
56  const unsigned int pc;
58  const unsigned short int pc2;
60  const unsigned short int hpc;
62  const bool condBranch;
63 
67  static inline unsigned int hash1(unsigned int a)
68  {
69  a = (a ^ 0xdeadbeef) + (a<<4);
70  a = a ^ (a>>10);
71  a = a + (a<<7);
72  a = a ^ (a>>13);
73  return a;
74  }
75 
76  static inline unsigned int hash2(unsigned int key)
77  {
78  int c2 = 0x27d4eb2d; // a prime or an odd constant
79  key = (key ^ 61) ^ (key >> 16);
80  key = key + (key << 3);
81  key = key ^ (key >> 4);
82  key = key * c2;
83  key = key ^ (key >> 15);
84  return key;
85  }
86 
87  static inline unsigned int hash(unsigned int key, unsigned int i)
88  {
89  return hash2(key) * i + hash1(key);
90  }
91 
92  static inline unsigned int hashPC(unsigned int pc, int pcshift)
93  {
94  if (pcshift < 0) {
95  return hash(pc, -pcshift);
96  } else if (pcshift < 11) {
97  unsigned int x = pc;
98  x ^= (pc >> pcshift);
99  return x;
100  } else {
101  return pc >> (pcshift-11);
102  }
103  }
104 
105  public:
107  bool filtered;
111  int yout;
112 
113  MPPBranchInfo(Addr _pc, int pcshift, bool cb) : pc((unsigned int)_pc),
114  pc2(pc >> 2), hpc(hashPC(pc, pcshift)), condBranch(cb),
115  filtered(false), prediction(false), yout(0)
116  { }
117 
118  unsigned int getPC() const
119  {
120  return pc;
121  }
122  unsigned short int getPC2() const
123  {
124  return pc2;
125  }
126  unsigned short int getHPC() const
127  {
128  return hpc;
129  }
130  unsigned int getHashFilter(bool last_ghist_bit) const
131  {
132  return last_ghist_bit ^ hpc;
133  }
134  bool isUnconditional() const
135  {
136  return !condBranch;
137  }
138  };
139 
143  struct FilterEntry {
145  bool seenTaken;
148 
149  FilterEntry() : seenTaken(false), seenUntaken(false) {}
150 
152  bool alwaysNotTakenSoFar() const {
153  return seenUntaken & !seenTaken;
154  }
156  bool alwaysTakenSoFar() const {
157  return seenTaken & !seenUntaken;
158  }
160  bool neverSeen() const {
161  return !seenTaken && !seenUntaken;
162  }
163  };
164 
165 
175 
177  unsigned int index(Addr pc) const {
178  return (pc >> 2) % localHistories.size();
179  }
180  public:
181  LocalHistories(int nlocal_histories, int histo_len) :
182  localHistories(nlocal_histories), localHistoryLength(histo_len) {}
183 
185  unsigned int operator[](Addr pc) const
186  {
187  return localHistories[index(pc)];
188  }
189 
191  void update(Addr pc, bool value)
192  {
193  assert(localHistories.size() > 0);
194  unsigned int &pos = localHistories[index(pc)];
195  pos <<= 1;
196  pos |= value;
197  pos &= ((1<<localHistoryLength)-1);
198  }
199 
202  {
203  return localHistoryLength;
204  }
205 
207  int getSize() const
208  {
209  return localHistoryLength * localHistories.size();
210  }
211  };
212 
216  struct HistorySpec {
218  const int p1;
220  const int p2;
222  const int p3;
224  const double coeff;
226  const int size;
228  const int width;
231 
232  HistorySpec(int _p1, int _p2, int _p3, double _coeff, int _size,
233  int _width, MultiperspectivePerceptron &_mpp) : p1(_p1),
234  p2(_p2), p3(_p3), coeff(_coeff), size(_size), width(_width),
235  mpp(_mpp)
236  {}
237 
247  virtual unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t)
248  const = 0;
253  virtual void setBitRequirements() const {}
254  };
255 
257  const int blockSize;
258  const int pcshift;
259  const int threshold;
260  const int bias0;
261  const int bias1;
262  const int biasmostly0;
263  const int biasmostly1;
264  const int nbest;
265  const int tunebits;
266  const int hshift;
267  const unsigned long long int imli_mask1;
268  const unsigned long long int imli_mask4;
269  const unsigned long long int recencypos_mask;
270  const double fudge;
271  const int n_sign_bits;
272  const int pcbit;
273  const int decay;
274  const unsigned int record_mask;
275  const bool hash_taken;
276  const bool tuneonly;
277  const int extra_rounds;
278  const int speed;
279  const int budgetbits;
280  const bool speculative_update;
281 
283  static int xlat[];
285  static int xlat4[];
286 
288  struct ThreadData {
289  ThreadData(int num_filter, int n_local_histories,
290  int local_history_length, int assoc,
292  int path_length, int ghist_length, int block_size,
298  const std::vector<int> &table_sizes, int n_sign_bits);
299 
303 
304  void updateAcyclic(bool hashed_taken, unsigned int hpc) {
305  for (int i = 0; i < acyclic_histories.size(); i += 1) {
306  if (acyclic_histories[i].size() > 0) {
307  acyclic_histories[i][hpc%(i+2)] = hashed_taken;
308  acyclic2_histories[i][hpc%(i+2)] = hpc;
309  }
310  }
311  }
312 
321 
322  void insertRecency(unsigned int pc, int assoc) {
323  int i = 0;
324  for (i = 0; i < assoc; i += 1) {
325  if (recency_stack[i] == pc) {
326  break;
327  }
328  }
329  if (i == assoc) {
330  i = assoc-1;
331  recency_stack[i] = pc;
332  }
333  int j;
334  unsigned int b = recency_stack[i];
335  for (j = i; j >= 1; j -= 1) {
336  recency_stack[j] = recency_stack[j-1];
337  }
338  recency_stack[0] = b;
339  }
340 
343 
347  };
349 
353 
357  int assoc;
362  int theta;
371 
373  void insertModhistSpec(int p1, int p2) {
374  int j = insert(modhist_indices, p1);
375  if (modhist_lengths.size() < (j + 1)) {
376  modhist_lengths.resize(j + 1);
377  }
378  if (modhist_lengths[j] < p2 + 1) {
379  modhist_lengths[j] = p2 + 1;
380  }
381  if (p2 >= modghist_length) {
382  modghist_length = p2 + 1;
383  }
384  }
385 
387  void insertModpathSpec(int p1, int p2) {
388  int j = insert(modpath_indices, p1);
389  if (modpath_lengths.size() < (j + 1)) {
390  modpath_lengths.resize(j + 1);
391  }
392  if (modpath_lengths[j] < p2 + 1) {
393  modpath_lengths[j] = p2 + 1;
394  }
395  if (p2 >= path_length) {
396  path_length = p2 + 1;
397  }
398  }
399 
402  {
403  for (int i = 0; i < v.size(); i += 1) {
404  if (v[i] == x) {
405  return i;
406  }
407  }
408  v.push_back(x);
409  return v.size()-1;
410  }
411 
421  void computeBits(int num_filter_entries, int nlocal_histories,
422  int local_history_length, bool ignore_path_size);
423 
427  virtual void createSpecs() = 0;
428 
437  unsigned int getIndex(ThreadID tid, const MPPBranchInfo &bi,
438  const HistorySpec &spec, int index) const;
446  void findBest(ThreadID tid, std::vector<int> &best_preds) const;
447 
455  int computeOutput(ThreadID tid, MPPBranchInfo &bi);
456 
463  void train(ThreadID tid, MPPBranchInfo &bi, bool taken);
464 
473  void satIncDec(bool taken, bool &sign, int &c, int max_weight) const;
474 
476  void addSpec(HistorySpec *spec)
477  {
478  specs.push_back(spec);
479  }
480 
483  class GHIST : public HistorySpec {
484  public:
485  GHIST(int p1, int p2, double coeff, int size, int width,
487  : HistorySpec(p1, p2, 0, coeff, size, width, mpp)
488  {}
489 
490  unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const
491  override
492  {
493  return hash(mpp.threadData[tid]->ghist_words, mpp.blockSize, p1,
494  p2);
495  }
496 
497  static unsigned int hash(const std::vector<unsigned int> &ghist_words,
498  int block_size, int start_pos, int end_pos)
499  {
500  int a = start_pos;
501  int b = end_pos;
502 
503  unsigned int x = 0;
504  // am is the next multiple of block_size after a
505  int am = (((a/block_size)*block_size)+block_size);
506  // bm is the previous multiple of block_size before b
507  int bm = (b/block_size)*block_size;
508 
509  // the 0th bit of ghist_words[a/block_size] is the most recent bit.
510  // so the number of bits between a and am is the number to shift
511  // right?
512 
513  // start out x as remainder bits from the beginning:
514  // x = [ . . . . . b b b b b ]
515  x += ghist_words[a / block_size] >> (a-am);
516  // add in bits from the middle
517  for (int i=am; i<bm; i+=block_size) {
518  x += ghist_words[i / block_size];
519  }
520  // add in remainder bits from end:
521  // x += [ b b b b b . . . . . ]
522  unsigned int y = ghist_words[bm / block_size] & ((1<<(b - bm))-1);
523  x += y << (block_size - (b - bm));
524  return x;
525  }
526  void setBitRequirements() const override
527  {
528  if (mpp.ghist_length <= p2) {
529  mpp.ghist_length = p2 + 1;
530  }
531  }
532  };
533 
534  class ACYCLIC : public HistorySpec {
535  public:
536  ACYCLIC(int p1, int p2, int p3, double coeff, int size, int width,
538  : HistorySpec(p1, p2, p3, coeff, size, width, mpp)
539  {}
540 
541  unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const
542  override
543  {
544  int a = p1;
545  int shift = p2;
546  int style = p3;
547  std::vector<std::vector<bool>> &acyclic_histories =
548  mpp.threadData[tid]->acyclic_histories;
549  std::vector<std::vector<unsigned int>> &acyclic2_histories =
550  mpp.threadData[tid]->acyclic2_histories;
551 
552  unsigned int x = 0;
553  if (style == -1) {
554  unsigned int k = 0;
555  for (int i = 0; i < a + 2; i += 1) {
556  x ^= acyclic_histories[a][i] << k;
557  k += 1;
558  k %= mpp.blockSize;
559  }
560  } else {
561  for (int i = 0; i < a + 2; i += 1) {
562  x <<= shift;
563  x += acyclic2_histories[a][i];
564  }
565  }
566  return x;
567  }
568  void setBitRequirements() const override
569  {
570  if (mpp.acyclic_bits.size() < (p1 + 1)) {
571  mpp.acyclic_bits.resize(p1 + 1);
572  }
573  if (mpp.acyclic_bits[p1].size() < (p1 + 2)) {
574  mpp.acyclic_bits[p1].resize(p1 + 2, std::vector<bool>(2));
575  }
576  for (int j = 0; j < p1 + 2; j += 1) {
577  mpp.acyclic_bits[p1][j][!p3] = true;
578  }
579  }
580  };
581 
582  class MODHIST : public HistorySpec {
583  public:
584  MODHIST(int p1, int p2, double coeff, int size, int width,
586  : HistorySpec(p1, p2, 0, coeff, size, width, mpp)
587  {}
588 
589  unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const
590  override
591  {
592  int a = p1;
593  int b = p2;
594  std::vector<std::vector<bool>> &mod_histories =
595  mpp.threadData[tid]->mod_histories;
596 
597  unsigned int x = 0, k = 0;
598  for (int i = 0; i < b; i += 1) {
599  x ^= mod_histories[a][i] << k;
600  k += 1;
601  k %= mpp.blockSize;
602  }
603  return x;
604  }
605  void setBitRequirements() const override
606  {
607  mpp.insertModhistSpec(p1, p2);
608  }
609  };
610 
611  class BIAS : public HistorySpec {
612  public:
613  BIAS(double coeff, int size, int width,
615  : HistorySpec(0, 0, 0, coeff, size, width, mpp)
616  {}
617 
618  unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const
619  override
620  {
621  return 0;
622  }
623  };
624 
625 
626  class RECENCY : public HistorySpec {
627  public:
628  RECENCY(int p1, int p2, int p3, double coeff, int size, int width,
630  : HistorySpec(p1, p2, p3, coeff, size, width, mpp)
631  {}
632 
633  unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const
634  override
635  {
636  int depth = p1;
637  int shift = p2;
638  int style = p3;
639  std::vector<unsigned int short> &recency_stack =
640  mpp.threadData[tid]->recency_stack;
641 
642  if (style == -1) {
643  unsigned int x = 0;
644  for (int i = 0; i < depth; i += 1) {
645  x <<= shift;
646  x += recency_stack[i];
647  }
648  return x;
649  } else {
650  unsigned int x = 0, k = 0;
651  for (int i = 0; i < depth; i += 1) {
652  x ^= (!!(recency_stack[i] & (1 << shift))) << k;
653  k += 1;
654  k %= mpp.blockSize;
655  }
656  return x;
657  }
658  }
659  void setBitRequirements() const override
660  {
661  if (mpp.assoc < p1) {
662  mpp.assoc = p1;
663  }
664  mpp.doing_recency = true;
665  }
666  };
667 
668  class IMLI : public HistorySpec {
669  public:
670  IMLI(int p1, double coeff, int size, int width,
672  : HistorySpec(p1, 0, 0, coeff, size, width, mpp)
673  {}
674 
675  unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const
676  override
677  {
678  assert(p1 >= 1);
679  assert(p1 <= 4);
680  return mpp.threadData[tid]->imli_counter[p1-1];
681  }
682 
683  void setBitRequirements() const override
684  {
685  mpp.imli_counter_bits[p1 - 1] = 32;
686  }
687  };
688 
689  class PATH : public HistorySpec {
690  public:
691  PATH(int p1, int p2, int p3, double coeff, int size, int width,
693  : HistorySpec(p1, p2, p3, coeff, size, width, mpp)
694  {}
695 
696  unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const
697  override
698  {
699  int depth = p1;
700  int shift = p2;
701  int style = p3;
702  std::vector<unsigned short int> &path_history =
703  mpp.threadData[tid]->path_history;
704 
705  if (style == -1) {
706  unsigned int x = 0;
707  for (int i = 0; i < depth; i += 1) {
708  x <<= shift;
709  x += path_history[i];
710  }
711  return x;
712  } else {
713  unsigned int x = 0;
714  int bm = (depth / mpp.blockSize) * mpp.blockSize;
715  for (int i = 0; i < bm; i += mpp.blockSize) {
716  for (int j = 0; j < mpp.blockSize; j += 1) {
717  x ^= (!!(path_history[i + j] & (1 << shift))) << j;
718  }
719  }
720  int k = 0;
721  for (int i = bm; i < depth; i += 1) {
722  x ^= (!!(path_history[i] & (1 << shift))) << k++;
723  }
724  return x;
725  }
726  }
727  void setBitRequirements() const override
728  {
729  if (mpp.path_length <= p1) {
730  mpp.path_length = p1 + 1;
731  }
732  }
733  };
734 
735  class LOCAL : public HistorySpec {
736  public:
737  LOCAL(int p1, double coeff, int size, int width,
739  : HistorySpec(p1, 0, 0, coeff, size, width, mpp)
740  {}
741 
742  unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const
743  override
744  {
745  unsigned int x = mpp.threadData[tid]->localHistories[pc];
746  if (p1 != -1) {
747  x &= ((1 << p1) - 1);
748  }
749  return x;
750  }
751  void setBitRequirements() const override
752  {
753  mpp.doing_local = true;
754  }
755  };
756 
757  class MODPATH : public HistorySpec {
758  public:
759  MODPATH(int p1, int p2, int p3, double coeff, int size, int width,
761  : HistorySpec(p1, p2, p3, coeff, size, width, mpp)
762  {}
763 
764  unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const
765  override
766  {
767  int a = p1;
768  int depth = p2;
769  int shift = p3;
770 
771  unsigned int x = 0;
772  for (int i=0; i<depth; i += 1) {
773  x <<= shift;
774  x += mpp.threadData[tid]->modpath_histories[a][i];
775  }
776  return x;
777  }
778  void setBitRequirements() const override
779  {
780  mpp.insertModpathSpec(p1, p2);
781  }
782  };
783 
784  class GHISTPATH : public HistorySpec {
785  public:
786  GHISTPATH(int p1, int p2, int p3, double coeff, int size, int width,
788  : HistorySpec(p1, p2, p3, coeff, size, width, mpp)
789  {}
790 
791  unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const
792  override
793  {
794  int depth = p1;
795  int shift = p2;
796  int style = p3;
797  std::vector<unsigned int> &ghist_words =
798  mpp.threadData[tid]->ghist_words;
799  std::vector<unsigned short int> &path_history =
800  mpp.threadData[tid]->path_history;
801 
802  if (style == -1) {
803  unsigned int x = 0;
804  int bm = (depth / mpp.blockSize) * mpp.blockSize;
805  unsigned int w;
806  for (int i = 0; i < bm; i += mpp.blockSize) {
807  w = ghist_words[i / mpp.blockSize];
808  for (int j = 0; j < mpp.blockSize; j += 1) {
809  x <<= shift;
810  x += (path_history[i + j] << 1) | (w & 1);
811  w >>= 1;
812  }
813  }
814  w = ghist_words[bm / mpp.blockSize];
815  for (int i = bm; i < depth; i += 1) {
816  x <<= shift;
817  x += (path_history[i] << 1) | (w & 1);
818  w >>= 1;
819  }
820  return x;
821  } else {
822  unsigned int x = 0;
823  int bm = (depth / mpp.blockSize) * mpp.blockSize;
824  unsigned int w = 0;
825  for (int i = 0; i < bm; i += mpp.blockSize) {
826  w = ghist_words[i / mpp.blockSize];
827  for (int j = 0; j < mpp.blockSize; j += 1) {
828  x ^= (!!(path_history[i + j] & (1 << shift))) << j;
829  x ^= (w & 1) << j;
830  w >>= 1;
831  }
832  }
833  w = ghist_words[bm/mpp.blockSize];
834  int k = 0;
835  for (int i = bm; i < depth; i += 1) {
836  x ^= (!!(path_history[i] & (1 << shift))) << k;
837  x ^= (w & 1) << k;
838  w >>= 1;
839  k += 1;
840  }
841  return x;
842  }
843  }
844 
845  void setBitRequirements() const override
846  {
847  if (mpp.ghist_length <= p1) {
848  mpp.ghist_length = p1 + 1;
849  }
850  if (mpp.path_length <= p1) {
851  mpp.path_length = p1 + 1;
852  }
853  }
854  };
855 
856  class GHISTMODPATH : public HistorySpec {
857  public:
858  GHISTMODPATH(int p1, int p2, int p3, double coeff, int size, int width,
860  : HistorySpec(p1, p2, p3, coeff, size, width, mpp)
861  {}
862 
863  unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const
864  override
865  {
866  int a = p1;
867  int depth = p2;
868  int shift = p3;
869  std::vector<std::vector<unsigned short int>> &modpath_histories =
870  mpp.threadData[tid]->modpath_histories;
871  std::vector<std::vector<bool>> &mod_histories =
872  mpp.threadData[tid]->mod_histories;
873 
874  unsigned int x = 0;
875  for (int i = 0; i < depth; i += 1) {
876  x <<= shift;
877  x += (modpath_histories[a][i] << 1) | mod_histories[a][i];
878  }
879  return x;
880  }
881  void setBitRequirements() const override
882  {
883  mpp.insertModhistSpec(p1, p2);
884  mpp.insertModpathSpec(p1, p2);
885  }
886  };
887 
888  class BLURRYPATH : public HistorySpec {
889  public:
890  BLURRYPATH(int p1, int p2, int p3, double coeff, int size, int width,
892  : HistorySpec(p1, p2, p3, coeff, size, width, mpp)
893  {}
894 
895  unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const
896  override
897  {
898  int scale = p1;
899  int depth = p2;
900  int shiftdelta = p3;
901 
902  if (shiftdelta == -1) shiftdelta = 0;
903  int sdint = shiftdelta >> 2;
904  int sdfrac = shiftdelta & 3;
905  unsigned int x = 0;
906  int shift = 0;
907  int count = 0;
908  for (int i = 0; i < depth; i += 1) {
909  x += mpp.threadData[tid]->blurrypath_histories[scale][i] >>
910  shift;
911  count += 1;
912  if (count == sdfrac) {
913  shift += sdint;
914  count = 0;
915  }
916  }
917  return x;
918 
919  }
920  void setBitRequirements() const override
921  {
922  if (mpp.blurrypath_bits.size() < (p1 + 1)) {
923  mpp.blurrypath_bits.resize(p1 + 1);
924  }
925  if (mpp.blurrypath_bits[p1].size() < p2) {
926  mpp.blurrypath_bits[p1].resize(p2);
927  }
928  for (int j = 0; j < p2; j += 1) {
929  mpp.blurrypath_bits[p1][j] = 32 - p1;
930  }
931  }
932  };
933 
934  class RECENCYPOS : public HistorySpec {
935  public:
936  RECENCYPOS(int p1, double coeff, int size, int width,
938  : HistorySpec(p1, 0, 0, coeff, size, width, mpp)
939  {}
940 
941  unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const
942  override
943  {
944  return hash(mpp.threadData[tid]->recency_stack, mpp.table_sizes,
945  pc2, p1, t);
946  }
947 
948  static unsigned int hash(
949  const std::vector<unsigned int short> &recency_stack,
950  const std::vector<int> &table_sizes, unsigned short int pc, int l,
951  int t)
952  {
953  // search for the PC
954 
955  for (int i = 0; i < l; i += 1) {
956  if (recency_stack[i] == pc) {
957  return i * table_sizes[t] / l;
958  }
959  }
960 
961  // return last index in table on a miss
962 
963  return table_sizes[t] - 1;
964  }
965 
966  void setBitRequirements() const override
967  {
968  if (mpp.assoc < p1) {
969  mpp.assoc = p1;
970  }
971  mpp.doing_recency = true;
972  }
973  };
974 
975  class SGHISTPATH : public HistorySpec {
976  public:
977  SGHISTPATH(int p1, int p2, int p3, double coeff, int size, int width,
979  : HistorySpec(p1, p2, p3, coeff, size, width, mpp)
980  {}
981 
982  unsigned int getHash(ThreadID tid, Addr pc, Addr pc2, int t) const
983  override
984  {
985  int a = p1;
986  int b = p2;
987  int shift = p3;
988  std::vector<unsigned int> &ghist_words =
989  mpp.threadData[tid]->ghist_words;
990  std::vector<unsigned short int> &path_history =
991  mpp.threadData[tid]->path_history;
992 
993  unsigned int x = 0;
994  int bm = (b / mpp.blockSize) * mpp.blockSize;
995  unsigned int w;
996  for (int i = a; i < bm; i += mpp.blockSize) {
997  w = ghist_words[i / mpp.blockSize];
998  for (int j = 0; j < mpp.blockSize; j += 1) {
999  x <<= shift;
1000  x += (path_history[i+j] << 1) | (w & 1);
1001  w >>= 1;
1002  }
1003  }
1004  w = ghist_words[bm / mpp.blockSize];
1005  for (int i = bm; i < b; i += 1) {
1006  x <<= shift;
1007  x += (path_history[i] << 1) | (w & 1);
1008  w >>= 1;
1009  }
1010  return x;
1011  }
1012  };
1013 
1014  public:
1015  MultiperspectivePerceptron(const MultiperspectivePerceptronParams *params);
1016 
1022  void setExtraBits(int bits);
1023 
1024  void init() override;
1025 
1026  void uncondBranch(ThreadID tid, Addr pc, void * &bp_history) override;
1027  void squash(ThreadID tid, void *bp_history) override;
1028  bool lookup(ThreadID tid, Addr instPC, void * &bp_history) override;
1029  void update(ThreadID tid, Addr instPC, bool taken,
1030  void *bp_history, bool squashed,
1031  const StaticInstPtr & inst,
1032  Addr corrTarget = MaxAddr) override;
1033  void btbUpdate(ThreadID tid, Addr branch_addr, void* &bp_history) override;
1034 };
1035 #endif//__CPU_PRED_MULTIPERSPECTIVE_PERCEPTRON_HH__
void updateAcyclic(bool hashed_taken, unsigned int hpc)
count
Definition: misc.hh:705
Base class to implement the predictor tables.
MODPATH(int p1, int p2, int p3, double coeff, int size, int width, MultiperspectivePerceptron &mpp)
const unsigned short int pc2
pc of the branch, shifted 2 bits to the right
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...
Bitfield< 30, 0 > index
void uncondBranch(ThreadID tid, Addr pc, void *&bp_history) override
Bitfield< 28 > v
const Addr MaxAddr
Definition: types.hh:166
BLURRYPATH(int p1, int p2, int p3, double coeff, int size, int width, MultiperspectivePerceptron &mpp)
Bitfield< 7 > i
MODHIST(int p1, int p2, double coeff, int size, int width, MultiperspectivePerceptron &mpp)
unsigned int index(Addr pc) const
Index function given the pc of the branch.
bool neverSeen() const
Whether this branch has been observed before.
std::vector< std::vector< unsigned int > > blurrypath_histories
unsigned int getHashFilter(bool last_ghist_bit) const
const double coeff
Coefficient of the feature, models the accuracy of the feature.
Bitfield< 3 > am
Definition: miscregs.hh:130
Bitfield< 8 > a
Bitfield< 6 > c2
const int blockSize
Predictor parameters.
MultiperspectivePerceptron(const MultiperspectivePerceptronParams *params)
static int xlat4[]
Transfer function for 5-width tables.
std::vector< std::vector< unsigned int > > acyclic2_histories
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...
std::vector< std::vector< bool > > acyclic_histories
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...
Bitfield< 20, 16 > bi
Definition: types.hh:65
bool prediction
Result of the prediction (true is taken)
const bool condBranch
Whether this is a conditional branch.
void insertRecency(unsigned int pc, int assoc)
LOCAL(int p1, double coeff, int size, int width, MultiperspectivePerceptron &mpp)
void update(Addr pc, bool value)
Adds a history bit to the local history entry of a given branch.
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...
std::vector< std::vector< short int > > tables
History data is kept for each thread.
static unsigned int hash1(unsigned int a)
PC Hash functions.
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 setExtraBits(int bits)
Sets the starting number of storage bits to compute the number of table entries.
bool alwaysTakenSoFar() const
Whether this branch has always been observed as taken.
void insertModhistSpec(int p1, int p2)
Auxiliary function for MODHIST and GHISTMODPATH features.
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...
Bitfield< 7 > b
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...
void addSpec(HistorySpec *spec)
Add a table spec to the prefetcher.
static unsigned int hashPC(unsigned int pc, int pcshift)
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...
std::vector< std::vector< std::array< bool, 2 > > > sign_bits
PATH(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...
virtual void createSpecs()=0
Creates the tables of the predictor.
const Params * params() const
Definition: sim_object.hh:114
static int xlat[]
Transfer function for 6-width tables.
Bitfield< 6, 5 > shift
Definition: types.hh:127
bool seenUntaken
Has this branch been not taken at least once?
static unsigned int hash2(unsigned int key)
Bitfield< 23 > k
Definition: dt_constants.hh:80
const unsigned long long int imli_mask1
const int size
Pre-assigned size in bits assigned to this feature.
void update(ThreadID tid, Addr instPC, bool taken, void *bp_history, bool squashed, const StaticInstPtr &inst, Addr corrTarget=MaxAddr) override
Updates the BP with taken/not taken information.
std::vector< std::vector< bool > > mod_histories
void setBitRequirements() const override
Sets the size requirements of the table, used when initializing to set the proper size of the tables...
void squash(ThreadID tid, void *bp_history) override
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...
GHIST(int p1, int p2, double coeff, int size, int width, MultiperspectivePerceptron &mpp)
const unsigned short int hpc
pc of the branch, hashed
std::vector< ThreadData * > threadData
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...
const unsigned long long int recencypos_mask
Bitfield< 0 > w
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
void setBitRequirements() const override
Sets the size requirements of the table, used when initializing to set the proper size of the tables...
int getSize() const
Size in bits required by all history entries.
bool seenTaken
Has this branch been taken at least once?
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...
scale
Definition: types.hh:94
Bitfield< 12, 11 > mpp
Definition: registers.hh:621
Bitfield< 24 > j
std::vector< unsigned int short > recency_stack
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...
void setBitRequirements() const override
Sets the size requirements of the table, used when initializing to set the proper size of the tables...
bool filtered
Whether this branch has been filtered by the prefetcher.
Basically a wrapper class to hold both the branch predictor and the BTB.
Definition: bpred_unit.hh:67
int16_t ThreadID
Thread index/ID type.
Definition: types.hh:227
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)
GHISTPATH(int p1, int p2, int p3, double coeff, int size, int width, MultiperspectivePerceptron &mpp)
Bitfield< 29 > c
unsigned int getIndex(ThreadID tid, const MPPBranchInfo &bi, const HistorySpec &spec, int index) const
Get the position index of a predictor table.
Local history entries, each enty contains the history of directions taken by a given branch...
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
IMLI(int p1, double coeff, int size, int width, MultiperspectivePerceptron &mpp)
const unsigned long long int imli_mask4
HistorySpec(int _p1, int _p2, int _p3, double _coeff, int _size, int _width, MultiperspectivePerceptron &_mpp)
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...
bool doing_local
runtime values and data used to count the size in bits
GHISTMODPATH(int p1, int p2, int p3, double coeff, int size, int width, MultiperspectivePerceptron &mpp)
const int localHistoryLength
Size in bits of each history entry.
std::vector< unsigned int > localHistories
The array of histories.
std::vector< HistorySpec * > specs
Predictor tables.
bool alwaysNotTakenSoFar() const
Whether this branch has always been observed as not taken.
std::vector< std::vector< unsigned short int > > modpath_histories
unsigned int operator[](Addr pc) const
Obtains the local history entry of a given branch.
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.
BIAS(double coeff, int size, int width, MultiperspectivePerceptron &mpp)
Bitfield< 4 > width
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...
const int width
Width of the table in bits.
void train(ThreadID tid, MPPBranchInfo &bi, bool taken)
Trains the branch predictor with the given branch and direction.
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...
MultiperspectivePerceptron & mpp
Reference to the branch predictor class.
Bitfield< 5 > t
static unsigned int hash(unsigned int key, unsigned int i)
ACYCLIC(int p1, int p2, int p3, double coeff, int size, int width, MultiperspectivePerceptron &mpp)
T bits(T val, int first, int last)
Extract the bitfield from position &#39;first&#39; to &#39;last&#39; (inclusive) from &#39;val&#39; and right justify it...
Definition: bitfield.hh:72
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.
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...
Bitfield< 1 > x
Definition: types.hh:105
Bitfield< 5 > l
std::vector< std::vector< int > > blurrypath_bits
std::vector< std::vector< std::vector< bool > > > acyclic_bits
static unsigned int hash(const std::vector< unsigned int > &ghist_words, int block_size, int start_pos, int end_pos)
int insert(std::vector< int > &v, int x)
Auxiliary function used by insertModhistSpec and insertModpathSpec.
int getLocalHistoryLength() const
Returns the number of bits of each local history entry.
virtual void setBitRequirements() const
Sets the size requirements of the table, used when initializing to set the proper size of the tables...
SGHISTPATH(int p1, int p2, int p3, double coeff, int size, int width, MultiperspectivePerceptron &mpp)
std::vector< unsigned short int > path_history
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...
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 insertModpathSpec(int p1, int p2)
Auxiliary function for MODPATH and GHISTMODPATH features.
void setBitRequirements() const override
Sets the size requirements of the table, used when initializing to set the proper size of the tables...
LocalHistories(int nlocal_histories, int histo_len)
void setBitRequirements() const override
Sets the size requirements of the table, used when initializing to set the proper size of the tables...

Generated on Fri Feb 28 2020 16:26:59 for gem5 by doxygen 1.8.13