90c6d04e8bf9c2318a1b7b66958ee8d6978a3134
[IRC.git] / Robust / src / Runtime / bamboo / multicorecache.c
1 #ifdef GC_CACHE_ADAPT
2 #include "multicorecache.h"
3 #include "multicoremsg.h"
4 #include "multicoregcprofile.h"
5
6 gc_cache_revise_info_t gc_cache_revise_information;
7
8 /* This function initialize the gc_cache_revise_information. It should be 
9  * invoked before we start compaction.
10  */
11 void samplingDataReviseInit(struct moveHelper * orig,struct moveHelper * to) {
12   // initialize the destination page info
13   gc_cache_revise_information.to_page_start_va=to->ptr;
14   unsigned int toindex=(unsigned INTPTR)(to->base-gcbaseva)/BAMBOO_PAGE_SIZE;
15   gc_cache_revise_information.to_page_end_va=gcbaseva+BAMBOO_PAGE_SIZE*(toindex+1);
16   gc_cache_revise_information.to_page_index=toindex;
17   // initilaize the original page info
18   unsigned int origindex=((unsigned INTPTR)(orig->base-gcbaseva))/BAMBOO_PAGE_SIZE;
19   gc_cache_revise_information.orig_page_start_va=orig->ptr;
20   gc_cache_revise_information.orig_page_end_va=gcbaseva+BAMBOO_PAGE_SIZE*(origindex+1);
21   gc_cache_revise_information.orig_page_index=origindex;
22 }
23
24 /* This function computes the revised profiling data of the first closed destination 
25  * page of an object that acrosses multiple pages
26  */
27 void firstPageConvert(bool origclosefirst, unsigned INTPTR main_factor, unsigned INTPTR delta_factor) {
28   unsigned INTPTR topage=gc_cache_revise_information.to_page_index*NUMCORESACTIVE;
29   unsigned INTPTR oldpage=gc_cache_revise_information.orig_page_index*NUMCORESACTIVE;
30   int * newtable=&gccachesamplingtbl_r[topage];
31   int * oldtable=&gccachesamplingtbl[oldpage];
32   // compute the revised profiling info for the start destination page
33   if(origclosefirst) {
34     // the start original page closes first, now compute the revised profiling
35     // info for the start destination page.
36     // The start destination page = the rest of the start original page + 
37     //                              delta_fator from the next original page
38     int * oldtable_next=&gccachesamplingtbl[oldpage+NUMCORESACTIVE];
39     for(int tt = 0; tt < NUMCORESACTIVE; tt++) {
40       (*newtable)=(*newtable)+((*oldtable)*main_factor+(*oldtable_next)*delta_factor)>>BAMBOO_PAGE_SIZE_BITS;
41       newtable++;
42       oldtable++;
43       oldtable_next++;
44     }
45     // close the start original page 
46     gc_cache_revise_information.orig_page_start_va+=main_factor+delta_factor;
47     gc_cache_revise_information.orig_page_end_va+=BAMBOO_PAGE_SIZE;
48     gc_cache_revise_information.orig_page_index++;
49   } else {
50     // the start destination page closes first, now compute the revised 
51     // profiling info for it.
52     for(int tt = 0; tt < NUMCORESACTIVE; tt++) {
53       (*newtable)=(*newtable)+((*oldtable)*main_factor)>>BAMBOO_PAGE_SIZE_BITS;
54       newtable++;
55       oldtable++;
56     }
57     // record the new start of the original page
58     gc_cache_revise_information.orig_page_start_va+=main_factor;
59   }
60   // close the start original page and destination page
61   gc_cache_revise_information.to_page_start_va=gc_cache_revise_information.to_page_end_va;
62   gc_cache_revise_information.to_page_end_va+=BAMBOO_PAGE_SIZE;
63   gc_cache_revise_information.to_page_index++;
64 }
65
66 /* This function computes the revised profiling info for closed destination 
67  * pages that are occupied by one object that acrosses multiple pages.
68  * the destination page = main_factor from the first unclosed original page 
69  *                       + delta_factor from the next unclosed original page
70  */
71 void restClosedPageConvert(void * current_ptr, unsigned INTPTR main_factor, unsigned INTPTR delta_factor) {
72   while(gc_cache_revise_information.to_page_end_va<=current_ptr) {
73     unsigned INTPTR topage=gc_cache_revise_information.to_page_index*NUMCORESACTIVE;
74     unsigned INTPTR oldpage=gc_cache_revise_information.orig_page_index*NUMCORESACTIVE;
75     int *newtable=&gccachesamplingtbl_r[topage];
76     int *oldtable=&gccachesamplingtbl[oldpage];
77     int *oldtable_next=&gccachesamplingtbl[oldpage+NUMCORESACTIVE];
78
79     for(int tt = 0; tt < NUMCORESACTIVE; tt++) {
80       (*newtable)=(*newtable)+((*oldtable)*main_factor+(*oldtable_next)*delta_factor)>>BAMBOO_PAGE_SIZE_BITS;
81       newtable++;
82       oldtable++;
83       oldtable_next++;
84     }
85
86     // close the original page and the destination page
87     gc_cache_revise_information.orig_page_start_va+=BAMBOO_PAGE_SIZE;
88     gc_cache_revise_information.orig_page_end_va+=BAMBOO_PAGE_SIZE;
89     gc_cache_revise_information.orig_page_index++;
90     gc_cache_revise_information.to_page_start_va=gc_cache_revise_information.to_page_end_va;
91     gc_cache_revise_information.to_page_end_va+=BAMBOO_PAGE_SIZE;
92     gc_cache_revise_information.to_page_index++;
93   }
94 }
95
96 /* This function computes the revised profiling info for the last
97  * destination page of an object that acrosses multiple pages.
98  */
99 void lastPageConvert(void * current_ptr) {
100   unsigned INTPTR to_factor=current_ptr-gc_cache_revise_information.to_page_start_va;
101   unsigned INTPTR topage=gc_cache_revise_information.to_page_index*NUMCORESACTIVE;
102   unsigned INTPTR oldpage=gc_cache_revise_information.orig_page_index*NUMCORESACTIVE;
103   int *newtable=&gccachesamplingtbl_r[topage];
104   int *oldtable=&gccachesamplingtbl[oldpage];
105
106   for(int tt = 0; tt < NUMCORESACTIVE; tt++) {
107     (*newtable)=(*newtable)+((*oldtable)*to_factor)>>BAMBOO_PAGE_SIZE_BITS;
108     newtable++;
109     oldtable++;
110   }
111   // do not need to set gc_cache_revise_information here for the last 
112   // original/destination page as it will be set in completePageConvert()
113 }
114
115 /* This function converts multiple original pages profiling data to multiple 
116  * destination pages' profiling data
117  */
118 void samplingDataConvertMultiple(void * current_ptr) {
119   // first decide which page close first: original or destination?
120   unsigned INTPTR to_factor=(unsigned INTPTR)(gc_cache_revise_information.to_page_end_va-gc_cache_revise_information.to_page_start_va);
121   unsigned INTPTR orig_factor=(unsigned INTPTR)(gc_cache_revise_information.orig_page_end_va-gc_cache_revise_information.orig_page_start_va);
122   bool origclosefirst=to_factor>orig_factor;
123   unsigned INTPTR delta_factor=(origclosefirst)?(to_factor-orig_factor):(orig_factor-to_factor);
124   unsigned INTPTR main_factor=(origclosefirst)?orig_factor:to_factor;
125
126   // compute the revised profiling info for the start destination page
127   firstPageConvert(origclosefirst, main_factor, delta_factor);
128   // update main_factor/delta_factor
129   if(origclosefirst) {
130     // for the following destination pages that are fully used:
131     // the destination page = (page_size-delta_factor) from the 
132     //                        first unclosed original page + delta_factor 
133     //                        from the next unclosed original page
134     // we always use main_factor to represent the factor from the first 
135     // unclosed original page
136     main_factor=BAMBOO_PAGE_SIZE-delta_factor;
137   } else {
138     // for the following destination pages that are fully used:
139     // the destination page = delta_factor from the first unclosed original    
140     //                        page + (page_size-delta_factor) from the next 
141     //                        unclosed original page
142     // we always use main_factor to represent the factor from the first
143     // unclosed original page
144     main_factor=delta_factor;
145     delta_factor=BAMBOO_PAGE_SIZE-delta_factor;
146   }
147
148   // compute the revised profiling info for the following closed destination
149   // pages
150   restClosedPageConvert(current_ptr, main_factor, delta_factor);
151
152   // compute the revised profiling info for the last destination page if needed
153   lastPageConvert(current_ptr);
154 }
155
156 /* This function converts originial pages' profiling data to destination pages'
157  * profiling data.
158  * The parameter current_ptr indicates the current position in the destination 
159  * pages.
160  * Note that there could be objects that across pages. In such cases, there are 
161  * multiple orig/to pages are closed and all these to pages' profiling data 
162  * should be properly updated.
163  */
164 void samplingDataConvert(void * current_ptr) {
165   if(gc_cache_revise_information.to_page_end_va<current_ptr) {
166     // multiple pages are closed
167     samplingDataConvertMultiple(current_ptr);
168   } else {
169     unsigned INTPTR tmp_factor=(unsigned INTPTR)(current_ptr-gc_cache_revise_information.to_page_start_va);
170     if(tmp_factor) {
171       unsigned INTPTR topage=gc_cache_revise_information.to_page_index*NUMCORESACTIVE;
172       unsigned INTPTR oldpage=gc_cache_revise_information.orig_page_index*NUMCORESACTIVE;
173       int * newtable=&gccachesamplingtbl_r[topage];
174       int * oldtable=&gccachesamplingtbl[oldpage];
175   
176       for(int tt = 0; tt < NUMCORESACTIVE; tt++) {
177         (*newtable)=(*newtable)+((*oldtable)*tmp_factor)>>BAMBOO_PAGE_SIZE_BITS;
178         newtable++;
179         oldtable++;
180       }
181     }
182   }
183
184
185 /* This function computes the impact of an original page on a destination page
186  * in terms of profiling data. It can only be invoked when there is an original 
187  * page that is closed or a destination page that is closed. When finished 
188  * computing the revised profiling info of the current destination page, it 
189  * sets up the gc_cache_revise_information to the latest position in the 
190  * original page and the destination page.
191  */
192 void completePageConvert(void * origptr, void * toptr, void * current_ptr) {
193   bool closeToPage=(unsigned int)(toptr)>=(unsigned int)(gc_cache_revise_information.to_page_end_va);
194   bool closeOrigPage=(unsigned int)(origptr)>=(unsigned int)(gc_cache_revise_information.orig_page_end_va);
195   if(closeToPage||closeOrigPage) {
196     // end of one or more orig/to page
197     // compute the impact of the original page(s) for the desitination page(s)
198     samplingDataConvert(current_ptr);
199     // prepare for an new orig page
200     unsigned INTPTR tmp_index=((unsigned INTPTR)(origptr-gcbaseva))/BAMBOO_PAGE_SIZE;
201     gc_cache_revise_information.orig_page_start_va=origptr;
202     gc_cache_revise_information.orig_page_end_va=gcbaseva+BAMBOO_PAGE_SIZE*(tmp_index+1);
203     gc_cache_revise_information.orig_page_index=tmp_index;
204     gc_cache_revise_information.to_page_start_va=toptr;
205     if(closeToPage) {
206       unsigned INTPTR to_index=((unsigned INTPTR)(toptr-gcbaseva))/BAMBOO_PAGE_SIZE;
207       gc_cache_revise_information.to_page_end_va=gcbaseva+BAMBOO_PAGE_SIZE*(to_index+1);
208       gc_cache_revise_information.to_page_index=to_index;
209     }
210   }
211 }
212
213 // prepare for cache adaption:
214 //   -- flush the shared heap
215 //   -- clean dtlb entries
216 //   -- change cache strategy
217 void cacheAdapt_gc(bool isgccachestage) {
218   // flush the shared heap
219   BAMBOO_CACHE_FLUSH_L2();
220
221   // clean the dtlb entries
222   BAMBOO_CLEAN_DTLB();
223
224   // change the cache strategy
225   gccachestage = isgccachestage;
226
227
228 // the master core decides how to adapt cache strategy for the mutator 
229 // according to collected statistic data
230
231 // find the core that accesses the page #page_index most
232 #define CACHEADAPT_FIND_HOTTEST_CORE(page_index,hottestcore,hotfreq) \
233   { \
234     int *local_tbl=&gccachesamplingtbl_r[page_index*NUMCORESACTIVE]; \
235     for(int i = 0; i < NUMCORESACTIVE; i++) { \
236       int freq = *local_tbl; \
237       local_tbl++; \
238       if(hotfreq < freq) { \
239         hotfreq = freq; \
240         hottestcore = i; \
241       } \
242     } \
243   }
244 // find the core that accesses the page #page_index most and comput the total
245 // access time of the page at the same time
246 #define CACHEADAPT_FIND_HOTTEST_CORE_W_TOTALFREQ(page_index,hottestcore,hotfreq,totalfreq) \
247   { \
248     int *local_tbl=&gccachesamplingtbl_r[page_index*NUMCORESACTIVE]; \
249     for(int i = 0; i < NUMCORESACTIVE; i++) { \
250       int freq = *local_tbl; \
251       local_tbl++; \
252       totalfreq += freq; \
253       if(hotfreq < freq) { \
254         hotfreq = freq; \
255         hottestcore = i; \
256       } \
257     } \
258   }
259 // Set the policy as hosted by coren
260 // NOTE: (x,y) should be changed to (x+1, y+1)!!!
261 #define CACHEADAPT_POLICY_SET_HOST_CORE(policy, coren) \
262   { \
263     (policy).cache_mode = BAMBOO_CACHE_MODE_COORDS; \    
264     (policy).lotar_x = bamboo_cpu2coords[2*(coren)]+1; \
265     (policy).lotar_y = bamboo_cpu2coords[2*(coren)+1]+1; \
266   }
267 // store the new policy information at tmp_p in gccachepolicytbl
268 #define CACHEADAPT_CHANGE_POLICY_4_PAGE(tmp_p,page_index,policy) \
269   { \
270     ((int*)(tmp_p))[page_index] = (policy).word; \
271   }
272
273 // make all pages hfh
274 void cacheAdapt_policy_h4h(int coren){
275   unsigned int page_num=(BAMBOO_SHARED_MEM_SIZE)/(BAMBOO_PAGE_SIZE);
276   unsigned int page_gap=page_num/NUMCORESACTIVE;
277   unsigned int page_index=page_gap*coren;
278   unsigned int page_index_end=(coren==NUMCORESACTIVE-1)?page_num:(page_index+page_gap);
279   VA page_sva = gcbaseva+(BAMBOO_PAGE_SIZE)*page_index;
280   int * tmp_p = gccachepolicytbl;
281   for(; page_index < page_index_end; page_index++) {
282     bamboo_cache_policy_t policy = {0};
283     policy.cache_mode = BAMBOO_CACHE_MODE_HASH;
284     CACHEADAPT_CHANGE_POLICY_4_PAGE(tmp_p,page_index,policy);
285     page_sva += BAMBOO_PAGE_SIZE;
286   }
287
288
289 // make all pages local as non-cache-adaptable gc local mode
290 void cacheAdapt_policy_local(int coren){
291   unsigned int page_num=(BAMBOO_SHARED_MEM_SIZE)/(BAMBOO_PAGE_SIZE);
292   unsigned int page_gap=page_num/NUMCORESACTIVE;
293   unsigned int page_index=page_gap*coren;
294   unsigned int page_index_end=(coren==NUMCORESACTIVE-1)?page_num:(page_index+page_gap);
295   VA page_sva = gcbaseva+(BAMBOO_PAGE_SIZE)*page_index;
296   int * tmp_p = gccachepolicytbl;
297   for(; page_index < page_index_end; page_index++) {
298     bamboo_cache_policy_t policy = {0};
299     unsigned int block = 0;
300     BLOCKINDEX(block, (void *) page_sva);
301     unsigned int coren = gc_block2core[block%(NUMCORES4GC*2)];
302     CACHEADAPT_POLICY_SET_HOST_CORE(policy, coren);
303     CACHEADAPT_CHANGE_POLICY_4_PAGE(tmp_p,page_index,policy);
304     page_sva += BAMBOO_PAGE_SIZE;
305   }
306
307
308 void cacheAdapt_policy_hottest(int coren){
309   unsigned int page_num=(BAMBOO_SHARED_MEM_SIZE)/(BAMBOO_PAGE_SIZE);
310   unsigned int page_gap=page_num/NUMCORESACTIVE;
311   unsigned int page_index=page_gap*coren;
312   unsigned int page_index_end=(coren==NUMCORESACTIVE-1)?page_num:(page_index+page_gap);
313   VA page_sva = gcbaseva+(BAMBOO_PAGE_SIZE)*page_index;
314   int * tmp_p = gccachepolicytbl;
315   for(; page_index < page_index_end; page_index++) {
316     bamboo_cache_policy_t policy = {0};
317     unsigned int hottestcore = 0;
318     unsigned int hotfreq = 0;
319     CACHEADAPT_FIND_HOTTEST_CORE(page_index,hottestcore,hotfreq);
320     // TODO
321     // Decide the cache strategy for this page
322     // If decide to adapt a new cache strategy, write into the shared block of
323     // the gcsharedsamplingtbl. The mem recording information that has been 
324     // written is enough to hold the information.
325     // Format: page start va + cache strategy(hfh/(host core+[x,y]))
326     if(hotfreq != 0) {
327       // locally cache the page in the hottest core
328       CACHEADAPT_POLICY_SET_HOST_CORE(policy, hottestcore);
329     }
330     CACHEADAPT_CHANGE_POLICY_4_PAGE(tmp_p,page_index,policy);
331     page_sva += BAMBOO_PAGE_SIZE;
332   }
333
334
335 #define GC_CACHE_ADAPT_DOMINATE_THRESHOLD  1
336 // cache the page on the core that accesses it the most if that core accesses 
337 // it more than (GC_CACHE_ADAPT_DOMINATE_THRESHOLD)% of the total.  Otherwise,
338 // h4h the page.
339 void cacheAdapt_policy_dominate(int coren){
340   unsigned int page_num=(BAMBOO_SHARED_MEM_SIZE)/(BAMBOO_PAGE_SIZE);
341   unsigned int page_gap=page_num/NUMCORESACTIVE;
342   unsigned int page_index=page_gap*coren;
343   unsigned int page_index_end=(coren==NUMCORESACTIVE-1)?page_num:(page_index+page_gap);
344   VA page_sva = gcbaseva+(BAMBOO_PAGE_SIZE)*page_index;
345   int * tmp_p = gccachepolicytbl;
346   for(; page_index < page_index_end; page_index++) {
347     bamboo_cache_policy_t policy = {0};
348     unsigned int hottestcore = 0;
349     unsigned int totalfreq = 0;
350     unsigned int hotfreq = 0;
351     CACHEADAPT_FIND_HOTTEST_CORE_W_TOTALFREQ(page_index,hottestcore,hotfreq,totalfreq);
352     // Decide the cache strategy for this page
353     // If decide to adapt a new cache strategy, write into the shared block of
354     // the gcpolicytbl 
355     // Format: page start va + cache policy
356     if(hotfreq != 0) {
357       totalfreq=totalfreq>>GC_CACHE_ADAPT_DOMINATE_THRESHOLD;
358       if((unsigned int)hotfreq < (unsigned int)totalfreq) {
359         // use hfh
360         policy.cache_mode = BAMBOO_CACHE_MODE_HASH;
361         /*unsigned int block = 0;
362         BLOCKINDEX(block, (void *) page_sva);
363         unsigned int coren = gc_block2core[block%(NUMCORES4GC*2)];
364         CACHEADAPT_POLICY_SET_HOST_CORE(policy, coren);*/
365       } else {
366         // locally cache the page in the hottest core
367         CACHEADAPT_POLICY_SET_HOST_CORE(policy, hottestcore);
368       }     
369     }
370     CACHEADAPT_CHANGE_POLICY_4_PAGE(tmp_p,page_index,policy);
371     page_sva += BAMBOO_PAGE_SIZE;
372   }
373 }
374
375 unsigned int cacheAdapt_decision(int coren) {
376   BAMBOO_CACHE_MF();
377   // check the statistic data
378   // for each page, decide the new cache strategy
379 #ifdef GC_CACHE_ADAPT_POLICY1
380   cacheAdapt_policy_h4h(coren);
381 #elif defined GC_CACHE_ADAPT_POLICY2
382   cacheAdapt_policy_local(coren);
383 #elif defined GC_CACHE_ADAPT_POLICY3
384   cacheAdapt_policy_hottest(coren);
385 #elif defined GC_CACHE_ADAPT_POLICY4
386   cacheAdapt_policy_dominate(coren);
387 #endif
388 }
389
390 // adapt the cache strategy for the mutator
391 void cacheAdapt_mutator() {
392   BAMBOO_CACHE_MF();
393   // check the changes and adapt them
394   int * tmp_p = gccachepolicytbl;
395   unsigned int page_sva = gcbaseva;
396   for(; page_sva<gctopva; page_sva+=BAMBOO_PAGE_SIZE) {
397     // read out the policy
398     bamboo_cache_policy_t policy = (bamboo_cache_policy_t)(*(tmp_p));
399     // adapt the policy
400     if(policy.word != 0) {
401       bamboo_adapt_cache_policy(page_sva,policy,BAMBOO_PAGE_SIZE);
402     }
403     tmp_p += 1;
404   }
405 }
406
407 // Cache adapt phase process for clients
408 void cacheAdapt_phase_client() {
409   WAITFORGCPHASE(CACHEPOLICYPHASE);
410   GC_PRINTF("Start cachepolicy phase\n");
411   cacheAdapt_decision(BAMBOO_NUM_OF_CORE);
412   //send init finish msg to core coordinator
413   send_msg_2(STARTUPCORE, GCFINISHCACHEPOLICY, BAMBOO_NUM_OF_CORE);
414   GC_PRINTF("Finish cachepolicy phase\n");
415
416   WAITFORGCPHASE(PREFINISHPHASE);
417   GC_PRINTF("Start prefinish phase\n");
418   // cache adapt phase
419   cacheAdapt_mutator();
420   cacheAdapt_gc(false);
421   //send init finish msg to core coordinator
422   send_msg_2(STARTUPCORE, GCFINISHPREF, BAMBOO_NUM_OF_CORE);
423   GC_PRINTF("Finish prefinish phase\n");
424   CACHEADAPT_SAMPING_RESET();
425   if(BAMBOO_NUM_OF_CORE < NUMCORESACTIVE) {
426     // zero out the gccachesamplingtbl
427     BAMBOO_MEMSET_WH(gccachesamplingtbl_local,0,size_cachesamplingtbl_local);  
428     BAMBOO_MEMSET_WH(gccachesamplingtbl_local_r,0,size_cachesamplingtbl_local_r);
429   }
430 }
431
432 extern unsigned long long gc_output_cache_policy_time;
433
434 // Cache adpat phase process for the master
435 void cacheAdapt_phase_master() {
436   GCPROFILE_ITEM();
437   unsigned long long tmpt = BAMBOO_GET_EXE_TIME();
438   CACHEADAPT_OUTPUT_CACHE_SAMPLING_R();
439   gc_output_cache_policy_time += (BAMBOO_GET_EXE_TIME()-tmpt);
440   // let all cores to parallelly process the revised profile data and decide 
441   // the cache policy for each page
442   gc_status_info.gcphase = CACHEPOLICYPHASE;
443   GC_SEND_MSG_1_TO_CLIENT(GCSTARTCACHEPOLICY);
444   GC_PRINTF("Start cachepolicy phase \n");
445   // cache adapt phase
446   cacheAdapt_decision(BAMBOO_NUM_OF_CORE);
447   GC_CHECK_ALL_CORE_STATUS();
448   BAMBOO_CACHE_MF();
449
450   // let all cores to adopt new policies
451   gc_status_info.gcphase = PREFINISHPHASE;
452   // Note: all cores should flush their runtime data including non-gc cores
453   GC_SEND_MSG_1_TO_CLIENT(GCSTARTPREF);
454   GC_PRINTF("Start prefinish phase \n");
455   // cache adapt phase
456   cacheAdapt_mutator();
457   cacheAdapt_gc(false);
458   GC_CHECK_ALL_CORE_STATUS();
459
460   CACHEADAPT_SAMPING_RESET();
461   if(BAMBOO_NUM_OF_CORE < NUMCORESACTIVE) {
462     // zero out the gccachesamplingtbl
463     BAMBOO_MEMSET_WH(gccachesamplingtbl_local,0,size_cachesamplingtbl_local);
464     BAMBOO_MEMSET_WH(gccachesamplingtbl_local_r,0,size_cachesamplingtbl_local_r);
465     BAMBOO_MEMSET_WH(gccachepolicytbl,0,size_cachepolicytbl);
466   }
467 }
468
469 // output original cache sampling data for each page
470 void gc_output_cache_sampling() {
471   //extern volatile bool gc_profile_flag;
472   //if(!gc_profile_flag) return;
473   unsigned int page_index = 0;
474   VA page_sva = 0;
475   unsigned int page_num = (BAMBOO_SHARED_MEM_SIZE) / (BAMBOO_PAGE_SIZE);
476   for(page_index = 0; page_index < page_num; page_index++) {
477     page_sva = gcbaseva + (BAMBOO_PAGE_SIZE) * page_index;
478     unsigned int block = 0;
479     BLOCKINDEX(block, (void *) page_sva);
480     unsigned int coren = gc_block2core[block%(NUMCORES4GC*2)];
481     printf("%x,  %d,  %d,  ",(int)page_sva,page_index,coren);
482     int * local_tbl = &gccachesamplingtbl[page_index*NUMCORESACTIVE];
483     for(int i = 0; i < NUMCORESACTIVE; i++) {
484       int freq = *local_tbl;
485       local_tbl++;
486       //if(freq != 0) {
487         printf("%d,  ", freq);
488       //}
489     }
490     printf("\n");
491   }
492   printf("=================\n");
493
494
495 // output revised cache sampling data for each page after compaction
496 void gc_output_cache_sampling_r() {
497   //extern volatile bool gc_profile_flag;
498   //if(!gc_profile_flag) return;
499   // TODO summary data
500   unsigned int sumdata[NUMCORESACTIVE][NUMCORESACTIVE];
501   for(int i = 0; i < NUMCORESACTIVE; i++) {
502     for(int j = 0; j < NUMCORESACTIVE; j++) {
503       sumdata[i][j] = 0;
504     }
505   }
506   tprintf("cache sampling_r \n");
507   unsigned int page_index = 0;
508   VA page_sva = 0;
509   unsigned int page_num = (BAMBOO_SHARED_MEM_SIZE) / (BAMBOO_PAGE_SIZE);
510   for(page_index = 0; page_index < page_num; page_index++) {
511     page_sva = gcbaseva + (BAMBOO_PAGE_SIZE) * page_index;
512     unsigned int block = 0;
513     BLOCKINDEX(block, (void *)page_sva);
514     unsigned int coren = gc_block2core[block%(NUMCORES4GC*2)];
515     printf(" %x,  %d,  %d,  ",(int)page_sva,page_index,coren);
516     int accesscore = 0; // TODO
517     int * local_tbl = &gccachesamplingtbl_r[page_index*NUMCORESACTIVE];
518     for(int i = 0; i < NUMCORESACTIVE; i++) {
519       int freq = *local_tbl; 
520       printf("%d,  ", freq);
521       if(freq != 0) {
522         accesscore++;// TODO
523       }
524       local_tbl++;
525     }
526     if(accesscore!=0) {
527       int * local_tbl = &gccachesamplingtbl_r[page_index*NUMCORESACTIVE];
528       for(int i = 0; i < NUMCORESACTIVE; i++) {
529         int freq = *local_tbl;
530         sumdata[accesscore-1][i]+=freq;
531         local_tbl++;
532       }
533     }
534   
535     printf("\n");
536   }
537   printf("+++++\n");
538   // TODO printout the summary data
539   for(int i = 0; i < NUMCORESACTIVE; i++) {
540     printf("%d  ", i);
541     for(int j = 0; j < NUMCORESACTIVE; j++) {
542       printf(" %d  ", sumdata[j][i]);
543     }
544     printf("\n");
545   }
546   printf("=================\n");
547
548 #endif // GC_CACHE_ADAPT