/************************************************************************************ * Micro Benchmark mbclss * ----------------------------- * File name: mbclss.c * Author : Yuanhua Yu * Date : 20/12/1999. * *------------------------------------------------------------------------------------- * * Function: Measuring the set size and subblock size of Cache Level I and Level II * * Methods: 1. Sequential array read access * 2. Random accessing sequence * 3. Stride accessing sequence * 4. Stride accessing sequence (improved) * * History: First version : 05/10/1999 * Second version: 20/12/1999 * *Parameters: STRIDE_START ---- intinial value of the stride : 1 (*4bytes) * STRIDE_END ---- max value of the stride : 1024 (*4bytes) * STEP_START ---- initial value of the step : 256 (bytes) * STEP_END ---- max value of the step : 1024*16(bytes) * TOTAL_ACCESS ---- number of the accesses done : (32768*1024*16) * * Variable: cache_size ---- capacity of the Level-I cache in KB * arr_size ---- size of the array accessed; * stride ---- number of items between two accessed items * step ---- increment of size of the array * * Functions: * seq_access() : * rand_access() : * stride_access() : * stride_access_1(): * random_sequence(): * set_parameters() : * get_parameters() : * write_file_head(): * *************************************************************************************/ #include #include #include #include #include #include #define STRIDE_START 1 //4 bytes #define STRIDE_END 1024 //4096 bytes #define STEP_START 256 //256 bytes #define STEP_END (1024*16) //16384bytes #define TOTAL_ACCESS (32768*1024*16) //operations #define ATYPE long /*------------------------------------------------------------------------------------*/ void seq_access(FILE *fp, long cache_size, long step); void rand_access(FILE *fp, long cache_size, long step); void stride_access(FILE *fp, long cache_size); void stride_access_1(FILE *fp, long cache_size); void random_sequence(volatile long *array, long max_index); void write_file_head(FILE *fp, char mname[255],int option); void set_parameters(char mname[15],long *cache_size); void get_parameters(char mname[15],char fname[25],long *cache_size); /*------------------------------------------------------------------------------------*/ void main(char **av, int ac) { long cache_size, step; char file_name[255],machine_name[255]; int option; FILE *fp; option = 1; while(option >=0 && option <6) { printf("\n\n Measuring the Set and Subblock Size of Cache Level-1\n"); printf("-----------------------------------------------------------\n"); printf(" 0. All of the tests\n"); printf(" 1. Set size\n"); printf(" 2. Set size (random sequence)\n"); printf(" 3. Subblock size\n"); printf(" 4. Subblock size (improved)\n"); printf(" 5. Set parameters\n"); printf(" 6. Exit\n"); printf("-----------------------------------------------------------\n"); printf(" Option (0 - 5): "); scanf("%d",&option); if(option ==5) { set_parameters(machine_name,&cache_size); continue; } get_parameters(machine_name,file_name,&cache_size); cache_size = cache_size * 1024; 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,1); for (step=STEP_START; step <= cache_size; step *= 2) { seq_access(fp, cache_size, step); } fprintf(fp,"\n\n"); } if(option == 2 || option == 0) { write_file_head(fp,machine_name,2); for (step=STEP_START; step <= cache_size; step *= 2) { rand_access(fp, cache_size, step); } fprintf(fp,"\n\n"); } if(option == 3 || option == 0) { write_file_head(fp,machine_name,3); stride_access(fp, cache_size); fprintf(fp,"\n\n"); } if(option == 4 || option == 0) { write_file_head(fp,machine_name,4); stride_access_1(fp, cache_size); fprintf(fp,"\n\n"); } } fclose(fp); } void seq_access(FILE *fp, long cache_size, long step ) /*-----------------------------------------------------------------------*/ /* Function: Measuring the cache set size using a sequential accessing */ /* sequence given the cache size */ /*-----------------------------------------------------------------------*/ { volatile ATYPE *va; register ATYPE s1; register long i; unsigned long start_time, stop_time, sum; long arr_size, arr_item; double time_cost, cost_per_op; printf("step = %d\n",step); fprintf(fp,"step = %d\n", step); for (arr_size=cache_size/2; arr_size <= cache_size*2; arr_size+=step) { arr_item = arr_size / (sizeof(ATYPE)); va = (ATYPE *) calloc(arr_item, sizeof(ATYPE)); sum=0; for (i=0; i0 || block_no >=max_index) { continue; } else { array[index] = block_no; index = block_no; break; } } } return; } void stride_access(FILE *fp, long cache_size) /*------------------------------------------------------------------------*/ /* Function: Measuring the cache line size using a sequential accessing */ /* sequence in terms of stride from 1 to 512 */ /*------------------------------------------------------------------------*/ { volatile ATYPE *va; register long i, j, s1, stride; unsigned long start_time,stop_time; double time_cost, cost_per_op; long arr_size, arr_item; arr_size = 4*cache_size; arr_item = arr_size / sizeof(ATYPE); va = (ATYPE *)calloc(arr_item,sizeof(ATYPE)); for (stride=STRIDE_START; stride