Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / rst / rstzip3 / rstzip_v3 / rz3_lruhash.h
CommitLineData
920dae64
AT
1/*
2* ========== Copyright Header Begin ==========================================
3*
4* OpenSPARC T2 Processor File: rz3_lruhash.h
5* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
6* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
7*
8* The above named program is free software; you can redistribute it and/or
9* modify it under the terms of the GNU General Public
10* License version 2 as published by the Free Software Foundation.
11*
12* The above named program is distributed in the hope that it will be
13* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15* General Public License for more details.
16*
17* You should have received a copy of the GNU General Public
18* License along with this work; if not, write to the Free Software
19* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
20*
21* ========== Copyright Header End ============================================
22*/
23/* rz3_lruhash.h
24 * fully-associative cache with lru replacement
25 */
26
27#ifndef _rz3_lruhash_h_
28#define _rz3_lruhash_h_
29
30#include <stdio.h>
31#include <strings.h>
32#include <sys/types.h>
33
34struct rz3_lruhash_elem {
35 uint64_t v;
36
37 rz3_lruhash_elem * next;
38 rz3_lruhash_elem * prev;
39
40
41 rz3_lruhash_elem() {
42 k = 0;
43 prev = next = NULL;
44 inited = false;
45 }
46
47 int GetKey() {
48 if (!inited) {
49 fprintf(stderr, "warning: rz3_lruhash: rz3_lruhash_elem key not set\n");
50 }
51 return k;
52 }
53
54 bool SetKey(int key) {
55 if (!inited) {
56 k = key;
57 inited = true;
58 return true;
59 } else {
60 fprintf(stderr, "warning: rz3_lruhash: rz3_lruhash_elem key already set\n");
61 return false;
62 }
63 }
64 private:
65 // "k" is equivalent to a java "final" variable - write once
66 int k; // "key", which is an index into a linear array in this implementation
67 bool inited;
68}; // rz3_lruhash_elem
69
70
71struct rz3_lruhash {
72
73 int nbits(uint64_t n) {
74 int rv = 1;
75 while(n>>rv) {
76 rv++;
77 }
78 return rv;
79 }
80
81 // size must be a power of 2
82 rz3_lruhash(int arg_size) {
83 size = arg_size;
84
85 idxbits = nbits(size-1);
86 arr = new rz3_lruhash_elem [size];
87
88 searchtbl = new rz3_lruhash_elem * [size];
89
90 Clear();
91
92 refs = misses = searchtbl_hits = 0;
93 }
94
95 void Clear() {
96 newest = arr;
97 oldest = arr+(size-1);
98
99 bzero(searchtbl, size*sizeof(rz3_lruhash_elem *));
100
101 int i;
102 for (i=0; i<size; i++) {
103 rz3_lruhash_elem * elem = arr+i;
104 elem->v = i;
105 elem->SetKey(i);
106 elem->prev = (elem == newest) ? NULL : arr+(i-1);
107 elem->next = (elem == oldest) ? NULL : arr+(i+1);
108 // insert into searchtbl
109 searchtbl[search_idx_fn(elem->v)] = elem;
110 }
111 } // rz3_lruhash(int arg_size)
112
113
114 ~rz3_lruhash() {
115 delete [] arr;
116 delete [] searchtbl;
117 } // ~rz3_lruhash()
118
119 // returns a "key" whose value is [0 .. size-1]
120 // and whose size is CEIL(log2(arg_size)) bits
121 bool Update(uint64_t v, int & k) {
122
123
124 k = -1;
125 refs++;
126
127 // first search for elem
128 int searchidx = search_idx_fn(v);
129 if ((searchtbl[searchidx] != NULL) && (searchtbl[searchidx]->v == v)) {
130 k = searchtbl[searchidx]->GetKey();
131 searchtbl_hits++;
132 } else {
133 int i;
134 for (i=0; i<size; i++) {
135 if (arr[i].v == v) {
136 k = i;
137 break;
138 }
139 }
140 }
141
142 bool hit;
143 if (k != -1) {
144 BringToFront(&(arr[k]));
145 hit = true;
146 } else {
147 k = oldest->GetKey();
148 oldest->v = v;
149 BringToFront(oldest);
150 misses++;
151 hit = false;
152 }
153
154 searchtbl[searchidx] = &(arr[k]);
155
156 return hit;
157 } // int Update(uint64_t v)
158
159 // if key is good, stores corresponding value in v and returns true. also brings (key,v) to the front of the MRU list
160 // returns false otherwise
161 bool Get(int key, uint64_t & v) {
162 if ((key < 0) || (key >= size)) return false;
163
164 v = arr[key].v;
165
166 BringToFront(&(arr[key]));
167 int searchidx = search_idx_fn(v);
168 searchtbl[searchidx] = &(arr[key]);
169 return true;
170 } // bool Get(int key, uint64_t & v)
171
172
173 void BringToFront(rz3_lruhash_elem * elem) {
174 if (elem == newest) return;
175
176 elem->prev->next = elem->next;
177 if (elem->next == NULL) {
178 oldest = elem->prev;
179 } else {
180 elem->next->prev = elem->prev;
181 }
182 elem->prev = NULL;
183 elem->next = newest;
184 newest->prev = elem;
185 newest = elem;
186 }
187
188 int search_idx_fn(uint64_t v) {
189 return (v & (size-1)) ^ ((v >> idxbits) & (size-1));
190 }
191
192 void Report(FILE * fp) {
193 fprintf(fp, "refs %lld misses %lld (%0.4f%%/ref)\n", refs, misses, misses*100.0/refs);
194 uint64_t hits = refs-misses;
195 fprintf(fp, " fasthits %lld (%0.4f%%/hit, %0.4f%%/ref)\n", searchtbl_hits, searchtbl_hits*100.0/hits, searchtbl_hits*100.0/refs);
196 }
197
198 int size;
199
200 int idxbits;
201
202 rz3_lruhash_elem * newest;
203 rz3_lruhash_elem * oldest;
204
205 rz3_lruhash_elem * arr;
206
207 rz3_lruhash_elem ** searchtbl; // search here first. if fails, search entire list
208
209 uint64_t refs;
210 uint64_t misses;
211 uint64_t searchtbl_hits;
212}; // struct rz3_lruhash
213
214#endif // _rz3_lruhash_h_
215