2 #include "multicorecache.h"
3 #include "multicoremsg.h"
4 #include "multicoregcprofile.h"
6 gc_cache_revise_info_t gc_cache_revise_information;
8 /* This function initialize the gc_cache_revise_information. It should be
9 * invoked before we start compaction.
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;
24 /* This function computes the revised profiling data of the first closed destination
25 * page of an object that acrosses multiple pages
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
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);
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++;
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);
57 // record the new start of the original page
58 gc_cache_revise_information.orig_page_start_va+=main_factor;
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++;
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
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];
79 for(int tt = 0; tt < NUMCORESACTIVE; tt++) {
80 (*newtable)=((*newtable)+(*oldtable)*main_factor+(*oldtable_next)*delta_factor);
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++;
96 /* This function computes the revised profiling info for the last
97 * destination page of an object that acrosses multiple pages.
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];
106 for(int tt = 0; tt < NUMCORESACTIVE; tt++) {
107 (*newtable)=((*newtable)+(*oldtable)*to_factor);
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()
115 /* This function converts multiple original pages profiling data to multiple
116 * destination pages' profiling data
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;
126 // compute the revised profiling info for the start destination page
127 firstPageConvert(origclosefirst, main_factor, delta_factor);
128 // update main_factor/delta_factor
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;
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;
148 // compute the revised profiling info for the following closed destination
150 restClosedPageConvert(current_ptr, main_factor, delta_factor);
152 // compute the revised profiling info for the last destination page if needed
153 lastPageConvert(current_ptr);
156 /* This function converts originial pages' profiling data to destination pages'
158 * The parameter current_ptr indicates the current position in the destination
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.
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);
169 unsigned INTPTR tmp_factor=(unsigned INTPTR)(current_ptr-gc_cache_revise_information.to_page_start_va);
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];
176 for(int tt = 0; tt < NUMCORESACTIVE; tt++) {
177 (*newtable)=((*newtable)+(*oldtable)*tmp_factor);
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.
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;
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;
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();
221 // clean the dtlb entries
224 // change the cache strategy
225 gccachestage = isgccachestage;
228 // the master core decides how to adapt cache strategy for the mutator
229 // according to collected statistic data
231 // find the core that accesses the page #page_index most
232 #define CACHEADAPT_FIND_HOTTEST_CORE(page_index,hottestcore,hotfreq) \
234 int *local_tbl=&gccachesamplingtbl_r[page_index*NUMCORESACTIVE]; \
235 for(int i = 0; i < NUMCORESACTIVE; i++) { \
236 int freq = *local_tbl; \
238 if(hotfreq < freq) { \
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) \
248 int *local_tbl=&gccachesamplingtbl_r[page_index*NUMCORESACTIVE]; \
249 for(int i = 0; i < NUMCORESACTIVE; i++) { \
250 int freq = *local_tbl; \
253 if(hotfreq < freq) { \
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) \
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; \
267 // store the new policy information at tmp_p in gccachepolicytbl
268 #define CACHEADAPT_CHANGE_POLICY_4_PAGE(tmp_p,page_index,policy) \
270 ((int*)(tmp_p))[page_index] = (policy).word; \
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;
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;
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);
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]))
327 // locally cache the page in the hottest core
328 CACHEADAPT_POLICY_SET_HOST_CORE(policy, hottestcore);
330 CACHEADAPT_CHANGE_POLICY_4_PAGE(tmp_p,page_index,policy);
331 page_sva += BAMBOO_PAGE_SIZE;
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,
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
355 // Format: page start va + cache policy
357 totalfreq=totalfreq>>GC_CACHE_ADAPT_DOMINATE_THRESHOLD;
358 if((unsigned int)hotfreq < (unsigned int)totalfreq) {
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);
366 // locally cache the page in the hottest core
367 CACHEADAPT_POLICY_SET_HOST_CORE(policy, hottestcore);
370 CACHEADAPT_CHANGE_POLICY_4_PAGE(tmp_p,page_index,policy);
371 page_sva += BAMBOO_PAGE_SIZE;
375 unsigned int cacheAdapt_decision(int coren) {
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);
390 // adapt the cache strategy for the mutator
391 void cacheAdapt_mutator() {
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));
400 if(policy.word != 0) {
401 bamboo_adapt_cache_policy(page_sva,policy,BAMBOO_PAGE_SIZE);
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");
416 WAITFORGCPHASE(PREFINISHPHASE);
417 GC_PRINTF("Start prefinish phase\n");
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);
432 extern unsigned long long gc_output_cache_policy_time;
434 // Cache adpat phase process for the master
435 void cacheAdapt_phase_master() {
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");
446 cacheAdapt_decision(BAMBOO_NUM_OF_CORE);
447 GC_CHECK_ALL_CORE_STATUS();
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");
456 cacheAdapt_mutator();
457 cacheAdapt_gc(false);
458 GC_CHECK_ALL_CORE_STATUS();
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);
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;
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;
487 printf("%d, ", freq);
492 printf("=================\n");
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;
500 unsigned int sumdata[NUMCORESACTIVE][NUMCORESACTIVE];
501 for(int i = 0; i < NUMCORESACTIVE; i++) {
502 for(int j = 0; j < NUMCORESACTIVE; j++) {
506 tprintf("cache sampling_r \n");
507 unsigned int page_index = 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; ///BAMBOO_PAGE_SIZE;
520 printf("%d, ", freq);
527 int * local_tbl = &gccachesamplingtbl_r[page_index];
528 for(int i = 0; i < NUMCORESACTIVE; i++) {
529 int freq = *local_tbl; ///BAMBOO_PAGE_SIZE;
530 sumdata[accesscore-1][i]+=freq;
537 // TODO printout the summary data
538 for(int i = 0; i < NUMCORESACTIVE; i++) {
540 for(int j = 0; j < NUMCORESACTIVE; j++) {
541 printf(" %d ", sumdata[j][i]);
545 printf("=================\n");
547 #endif // GC_CACHE_ADAPT