/************************************************************************************* * Microbench Benchmark: mbccl * ------------------------------------------ * Filename: mbccl.c * Author : Yuanhua Yu * Date : 25/12/1999 *------------------------------------------------------------------------------------- * * Function: 1.Measuring the cache size and associativity of Level-I cache and * * 2.Measuring the cache size and associativity of Level-II cache and * * 3.Measuring the hit read time of Level-I and Level-II cache. * * Methods: 1. Independent sequential array read access * 2. Dependent sequential array read but wait for the address * 3. Random accessing sequence but waiting for the address * * History: 10/10/1999 First version * 25/10/1999 Second version * 25/12/1999 Third version * * Parameters: TOTAL_ACCESS----- control the number of operations : (4096*4096*32) * ARR_SIZE_0 ----- array size starts(bytes) : 1024 * ARR_SIZE_1 ----- array size ends(bytes)-mode 1 : 32768 * ARR_SIZE_2 ----- array size ends(bytes)-mode 2 : 4194304 * ARR_STEP ----- step of array size increment(bytes): 1024 * STRIDE ----- distance between to accessed items : 8/16 (items) * * Variable: arr_size --- arr_size = arr_size / (sizeof(ATYPE))(items) * arr_mode --- increment mode of the array size : 0/1 * * Functions: * independent_access(): * wait_access() : * seq_circular() : * random_seq() : * random_sequence() : * set_parameters() : * get_parameters() : * write_file_head() : * ****************************************************************************************/ #include #include #include #include #include #include #define TOTAL_ACCESS (4096*4096*16) #define STRIDE 8 #define ARR_SIZE_0 1024 #define ARR_SIZE_1 (1024*32) #define ARR_SIZE_2 (1024*1024*8) #define ARR_STEP 1024 #define ATYPE long /*----------------------------------------------------------------------------------*/ void write_file_head(FILE *fp, char mname[255],long stride,int option); void independent_access(FILE *fp,long arr_size); void dependent_wait(FILE *fp,long arr_size); void seq_circular(volatile long *array,long max_index,long stride,long num_ways); void random_access(FILE *fp,long arr_size); void random_sequence(volatile long *array, long max_index); void set_parameters(char mname[15],int *step_mode); void get_parameters(char mname[15],char fname[25],int *step_mode); /*----------------------------------------------------------------------------------*/ int main(char **av, int ac) { int option, step_mode=0; long arr_size; char file_name[255],machine_name[255]; FILE *fp; option = 1; while(option>=0 && option<5) { printf("\n Cache Capacity and Associativity Measurement \n"); printf("----------------------------------------------------------\n"); printf(" 0. All of the above tests\n"); printf(" 1. Independent accessiing without waiting \n"); printf(" 2. Dependent accessing and waiting\n"); printf(" 3. Random accessing\n"); printf(" 4. Set parameters\n"); printf(" 5. Exit\n"); printf("----------------------------------------------------------\n"); printf(" Option(0-5) .... "); scanf("%d", &option); if(option ==6) { set_parameters(machine_name,&step_mode); continue; } get_parameters(machine_name,file_name,&step_mode); fp = fopen(file_name,"a+"); if(fp == NULL) { perror("Error: Can't open file !"); exit(1); } if (option == 1 || option == 0) { write_file_head(fp,machine_name,STRIDE*sizeof(ATYPE),1); if(step_mode == 0) for(arr_size=ARR_SIZE_0;arr_size<=ARR_SIZE_1;arr_size+=ARR_STEP) { independent_access(fp,arr_size); } if(step_mode == 1) for(arr_size=ARR_SIZE_0;arr_size<=ARR_SIZE_2;arr_size=arr_size*2) { independent_access(fp,arr_size); } fprintf(fp,"\n\n"); } if (option == 2 || option == 0 ) { write_file_head(fp,machine_name,STRIDE*sizeof(ATYPE),2); if(step_mode == 0) for(arr_size=ARR_SIZE_0;arr_size<=ARR_SIZE_1;arr_size+=ARR_STEP) { dependent_wait(fp,arr_size); } if(step_mode == 1) for(arr_size=ARR_SIZE_0;arr_size<=ARR_SIZE_2;arr_size=arr_size*2) { dependent_wait(fp,arr_size); } fprintf(fp,"\n\n"); } if (option == 3 || option == 0 ) { write_file_head(fp,machine_name,STRIDE*sizeof(ATYPE),3); if(step_mode == 0) for(arr_size=ARR_SIZE_0;arr_size<=ARR_SIZE_1;arr_size+=ARR_STEP) { random_access(fp,arr_size); } if(step_mode == 1) for(arr_size=ARR_SIZE_0;arr_size<=ARR_SIZE_2;arr_size=arr_size*2) { random_access(fp,arr_size); } fprintf(fp,"\n\n"); } } fclose(fp); return 0; } void independent_access(FILE *fp,long arr_size) /*--------------------------------------------------------------------------*/ /* Function: Measure the cache memory with a sequential accessing array */ /* */ /*--------------------------------------------------------------------------*/ { volatile ATYPE *va; register ATYPE s1; register long i,j,loop; unsigned long start_time,stop_time; double time_cost, cost_per_op; arr_size = arr_size / (sizeof(ATYPE)); va = (ATYPE *) calloc(arr_size, sizeof(ATYPE)); for (i=0; i0 || block_no>=max_index ) { continue; } else { array[index] = block_no; index = block_no; break; } } } return; } void set_parameters(char mname[15],int *step_mode) /*----------------------------------------------------------------------------*/ /* Function: Config the needed parameters from keyboard and */ /* form a name for the data file and save the them */ /* in the TLB_Config.data . */ /*----------------------------------------------------------------------------*/ { char fname[25]; FILE *fp; printf(" The Machine Name: "); scanf("%s",mname); printf(" Mode of array size increment(0/1): "); scanf("%d", step_mode); strcpy(fname,"Capacity_"); strcat(fname,mname); strcat(fname,".dat"); fp = fopen("Capacity_Config.dat","w"); if(fp == NULL) { perror("Error: Can't open file !"); exit(1); } fprintf(fp,"%s\n",mname); fprintf(fp,"%s\n",fname); fprintf(fp,"%d\n",*step_mode); fclose(fp); return; } void get_parameters(char mname[15],char fname[25],int *step_mode) /*---------------------------------------------------------------------------*/ /* Function: get the parameters needed from file TLB_Config.dat */ /*---------------------------------------------------------------------------*/ { FILE *fp; fp = fopen("Capacity_Config.dat","r"); if(fp == NULL) { perror("Error: Can't open file !"); exit(1); } fscanf(fp,"%s\n",mname); fscanf(fp,"%s\n",fname); fscanf(fp,"%d\n",step_mode); fclose(fp); return; } void write_file_head(FILE *fp,char mname[255],long stride,int option) /*----------------------------------------------------------------------------*/ /* Funtion: write some given parameters to the head of the data file */ /*----------------------------------------------------------------------------*/ { time_t tm; char time_buf[255]; time(&tm); strcpy(time_buf, ctime(&tm)); printf("\n\nTest date: %s", time_buf ); printf("----------------------------------------------------------\n"); fprintf(fp,"--------- Measurement of Cache Capacity -----------\n"); fprintf(fp,"\n Manchine: %s", mname ); fprintf(fp,"\nStride(bytes): %d", stride); fprintf(fp,"\n Test date: %s", time_buf ); if( option == 1) fprintf(fp," Method: Independent_access --- %d",option); else if (option == 2) fprintf(fp," Method: dependent_wait --- %d",option); else if (option == 3) fprintf(fp," Method: random_sequential --- %d",option); else ; fprintf(fp,"\n-----------------------------------------------------\n"); printf("ARR_SIZE(byte) Access_T(ns)\tTotal_T(s)\n"); fprintf(fp,"ARR_SIZE(byte) Access_T(ns)\tTotal_T(s)\n"); }