Michael Wei
/
ClockControl
see http://mbed.org/users/no2chem/notebook/mbed-clock-control--benchmarks/
Embed:
(wiki syntax)
Show/hide line numbers
core_main.c
00001 /* 00002 Author : Shay Gal-On, EEMBC 00003 00004 This file is part of EEMBC(R) and CoreMark(TM), which are Copyright (C) 2009 00005 All rights reserved. 00006 00007 EEMBC CoreMark Software is a product of EEMBC and is provided under the terms of the 00008 CoreMark License that is distributed with the official EEMBC COREMARK Software release. 00009 If you received this EEMBC CoreMark Software without the accompanying CoreMark License, 00010 you must discontinue use and download the official release from www.coremark.org. 00011 00012 Also, if you are publicly displaying scores generated from the EEMBC CoreMark software, 00013 make sure that you are in compliance with Run and Reporting rules specified in the accompanying readme.txt file. 00014 00015 EEMBC 00016 4354 Town Center Blvd. Suite 114-200 00017 El Dorado Hills, CA, 95762 00018 */ 00019 /* File: core_main.c 00020 This file contains the framework to acquire a block of memory, seed initial parameters, tun t he benchmark and report the results. 00021 */ 00022 #include "coremark.h" 00023 00024 /* Function: iterate 00025 Run the benchmark for a specified number of iterations. 00026 00027 Operation: 00028 For each type of benchmarked algorithm: 00029 a - Initialize the data block for the algorithm. 00030 b - Execute the algorithm N times. 00031 00032 Returns: 00033 NULL. 00034 */ 00035 static ee_u16 list_known_crc[] = {(ee_u16)0xd4b0,(ee_u16)0x3340,(ee_u16)0x6a79,(ee_u16)0xe714,(ee_u16)0xe3c1}; 00036 static ee_u16 matrix_known_crc[] = {(ee_u16)0xbe52,(ee_u16)0x1199,(ee_u16)0x5608,(ee_u16)0x1fd7,(ee_u16)0x0747}; 00037 static ee_u16 state_known_crc[] = {(ee_u16)0x5e47,(ee_u16)0x39bf,(ee_u16)0xe5a4,(ee_u16)0x8e3a,(ee_u16)0x8d84}; 00038 void *iterate(void *pres) { 00039 ee_u32 i; 00040 ee_u16 crc; 00041 core_results *res=(core_results *)pres; 00042 ee_u32 iterations=res->iterations; 00043 res->crc=0; 00044 res->crclist=0; 00045 res->crcmatrix=0; 00046 res->crcstate=0; 00047 00048 for (i=0; i<iterations; i++) { 00049 crc=core_bench_list(res,1); 00050 res->crc=crcu16(crc,res->crc); 00051 crc=core_bench_list(res,-1); 00052 res->crc=crcu16(crc,res->crc); 00053 if (i==0) res->crclist=res->crc; 00054 } 00055 return NULL; 00056 } 00057 00058 #if (SEED_METHOD==SEED_ARG) 00059 ee_s32 get_seed_args(int i, int argc, char *argv[]); 00060 #define get_seed(x) (ee_s16)get_seed_args(x,argc,argv) 00061 #define get_seed_32(x) get_seed_args(x,argc,argv) 00062 #else /* via function or volatile */ 00063 ee_s32 get_seed_32(int i); 00064 #define get_seed(x) (ee_s16)get_seed_32(x) 00065 #endif 00066 00067 #if (MEM_METHOD==MEM_STATIC) 00068 ee_u8 static_memblk[TOTAL_DATA_SIZE]; 00069 #endif 00070 char *mem_name[3] = {"Static","Heap","Stack"}; 00071 /* Function: main 00072 Main entry routine for the benchmark. 00073 This function is responsible for the following steps: 00074 00075 1 - Initialize input seeds from a source that cannot be determined at compile time. 00076 2 - Initialize memory block for use. 00077 3 - Run and time the benchmark. 00078 4 - Report results, testing the validity of the output if the seeds are known. 00079 00080 Arguments: 00081 1 - first seed : Any value 00082 2 - second seed : Must be identical to first for iterations to be identical 00083 3 - third seed : Any value, should be at least an order of magnitude less then the input size, but bigger then 32. 00084 4 - Iterations : Special, if set to 0, iterations will be automatically determined such that the benchmark will run between 10 to 100 secs 00085 00086 */ 00087 00088 #if MAIN_HAS_NOARGC 00089 MAIN_RETURN_TYPE mainCoreMark(void) { 00090 int argc=0; 00091 char *argv[1]; 00092 #else 00093 MAIN_RETURN_TYPE mainCoreMark(int argc, char *argv[]) { 00094 #endif 00095 ee_u16 i,j=0,num_algorithms=0; 00096 ee_s16 known_id=-1,total_errors=0; 00097 ee_u16 seedcrc=0; 00098 CORE_TICKS total_time; 00099 core_results results[MULTITHREAD]; 00100 #if (MEM_METHOD==MEM_STACK) 00101 ee_u8 stack_memblock[TOTAL_DATA_SIZE*MULTITHREAD]; 00102 #endif 00103 /* first call any initializations needed */ 00104 portable_init(&(results[0].port), &argc, argv); 00105 /* First some checks to make sure benchmark will run ok */ 00106 if (sizeof(struct list_head_s)>128) { 00107 ee_printf("list_head structure too big for comparable data!\n"); 00108 return MAIN_RETURN_VAL; 00109 } 00110 results[0].seed1=get_seed(1); 00111 results[0].seed2=get_seed(2); 00112 results[0].seed3=get_seed(3); 00113 results[0].iterations=get_seed_32(4); 00114 #if CORE_DEBUG 00115 results[0].iterations=1; 00116 #endif 00117 results[0].execs=get_seed_32(5); 00118 if (results[0].execs==0) { /* if not supplied, execute all algorithms */ 00119 results[0].execs=ALL_ALGORITHMS_MASK; 00120 } 00121 /* put in some default values based on one seed only for easy testing */ 00122 if ((results[0].seed1==0) && (results[0].seed2==0) && (results[0].seed3==0)) { /* validation run */ 00123 results[0].seed1=0; 00124 results[0].seed2=0; 00125 results[0].seed3=0x66; 00126 } 00127 if ((results[0].seed1==1) && (results[0].seed2==0) && (results[0].seed3==0)) { /* perfromance run */ 00128 results[0].seed1=0x3415; 00129 results[0].seed2=0x3415; 00130 results[0].seed3=0x66; 00131 } 00132 #if (MEM_METHOD==MEM_STATIC) 00133 results[0].memblock[0]=(void *)static_memblk; 00134 results[0].size=TOTAL_DATA_SIZE; 00135 results[0].err=0; 00136 #if (MULTITHREAD>1) 00137 #error "Cannot use a static data area with multiple contexts!" 00138 #endif 00139 #elif (MEM_METHOD==MEM_MALLOC) 00140 for (i=0 ; i<MULTITHREAD; i++) { 00141 ee_s32 malloc_override=get_seed(7); 00142 if (malloc_override != 0) 00143 results[i].size=malloc_override; 00144 else 00145 results[i].size=TOTAL_DATA_SIZE; 00146 results[i].memblock[0]=portable_malloc(results[i].size); 00147 results[i].seed1=results[0].seed1; 00148 results[i].seed2=results[0].seed2; 00149 results[i].seed3=results[0].seed3; 00150 results[i].err=0; 00151 results[i].execs=results[0].execs; 00152 } 00153 #elif (MEM_METHOD==MEM_STACK) 00154 for (i=0 ; i<MULTITHREAD; i++) { 00155 results[i].memblock[0]=stack_memblock+i*TOTAL_DATA_SIZE; 00156 results[i].size=TOTAL_DATA_SIZE; 00157 results[i].seed1=results[0].seed1; 00158 results[i].seed2=results[0].seed2; 00159 results[i].seed3=results[0].seed3; 00160 results[i].err=0; 00161 results[i].execs=results[0].execs; 00162 } 00163 #else 00164 #error "Please define a way to initialize a memory block." 00165 #endif 00166 /* Data init */ 00167 /* Find out how space much we have based on number of algorithms */ 00168 for (i=0; i<NUM_ALGORITHMS; i++) { 00169 if ((1<<(ee_u32)i) & results[0].execs) 00170 num_algorithms++; 00171 } 00172 for (i=0 ; i<MULTITHREAD; i++) 00173 results[i].size=results[i].size/num_algorithms; 00174 /* Assign pointers */ 00175 for (i=0; i<NUM_ALGORITHMS; i++) { 00176 ee_u32 ctx; 00177 if ((1<<(ee_u32)i) & results[0].execs) { 00178 for (ctx=0 ; ctx<MULTITHREAD; ctx++) 00179 results[ctx].memblock[i+1]=(char *)(results[ctx].memblock[0])+results[0].size*j; 00180 j++; 00181 } 00182 } 00183 /* call inits */ 00184 for (i=0 ; i<MULTITHREAD; i++) { 00185 if (results[i].execs & ID_LIST) { 00186 results[i].list=core_list_init(results[0].size, (list_head*) results[i].memblock[1],results[i].seed1); 00187 } 00188 if (results[i].execs & ID_MATRIX) { 00189 core_init_matrix(results[0].size, results[i].memblock[2], (ee_s32)results[i].seed1 | (((ee_s32)results[i].seed2) << 16), &(results[i].mat) ); 00190 } 00191 if (results[i].execs & ID_STATE) { 00192 core_init_state(results[0].size,results[i].seed1, (ee_u8*) results[i].memblock[3]); 00193 } 00194 } 00195 00196 /* automatically determine number of iterations if not set */ 00197 if (results[0].iterations==0) { 00198 secs_ret secs_passed=0; 00199 ee_u32 divisor; 00200 results[0].iterations=1; 00201 while (secs_passed < (secs_ret)1) { 00202 results[0].iterations*=10; 00203 start_time(); 00204 iterate(&results[0]); 00205 stop_time(); 00206 secs_passed=time_in_secs(get_time()); 00207 } 00208 /* now we know it executes for at least 1 sec, set actual run time at about 10 secs */ 00209 divisor=(ee_u32)secs_passed; 00210 if (divisor==0) /* some machines cast float to int as 0 since this conversion is not defined by ANSI, but we know at least one second passed */ 00211 divisor=1; 00212 results[0].iterations*=1+10/divisor; 00213 } 00214 /* perform actual benchmark */ 00215 start_time(); 00216 #if (MULTITHREAD>1) 00217 if (default_num_contexts>MULTITHREAD) { 00218 default_num_contexts=MULTITHREAD; 00219 } 00220 for (i=0 ; i<default_num_contexts; i++) { 00221 results[i].iterations=results[0].iterations; 00222 results[i].execs=results[0].execs; 00223 core_start_parallel(&results[i]); 00224 } 00225 for (i=0 ; i<default_num_contexts; i++) { 00226 core_stop_parallel(&results[i]); 00227 } 00228 #else 00229 iterate(&results[0]); 00230 #endif 00231 stop_time(); 00232 total_time=get_time(); 00233 /* get a function of the input to report */ 00234 seedcrc=crc16(results[0].seed1,seedcrc); 00235 seedcrc=crc16(results[0].seed2,seedcrc); 00236 seedcrc=crc16(results[0].seed3,seedcrc); 00237 seedcrc=crc16(results[0].size,seedcrc); 00238 00239 switch (seedcrc) { /* test known output for common seeds */ 00240 case 0x8a02: /* seed1=0, seed2=0, seed3=0x66, size 2000 per algorithm */ 00241 known_id=0; 00242 ee_printf("6k performance run parameters for coremark.\n"); 00243 break; 00244 case 0x7b05: /* seed1=0x3415, seed2=0x3415, seed3=0x66, size 2000 per algorithm */ 00245 known_id=1; 00246 ee_printf("6k validation run parameters for coremark.\n"); 00247 break; 00248 case 0x4eaf: /* seed1=0x8, seed2=0x8, seed3=0x8, size 400 per algorithm */ 00249 known_id=2; 00250 ee_printf("Profile generation run parameters for coremark.\n"); 00251 break; 00252 case 0xe9f5: /* seed1=0, seed2=0, seed3=0x66, size 666 per algorithm */ 00253 known_id=3; 00254 ee_printf("2K performance run parameters for coremark.\n"); 00255 break; 00256 case 0x18f2: /* seed1=0x3415, seed2=0x3415, seed3=0x66, size 666 per algorithm */ 00257 known_id=4; 00258 ee_printf("2K validation run parameters for coremark.\n"); 00259 break; 00260 default: 00261 total_errors=-1; 00262 break; 00263 } 00264 if (known_id>=0) { 00265 for (i=0 ; i<default_num_contexts; i++) { 00266 results[i].err=0; 00267 if ((results[i].execs & ID_LIST) && 00268 (results[i].crclist!=list_known_crc[known_id])) { 00269 ee_printf("[%u]ERROR! list crc 0x%04x - should be 0x%04x\n",i,results[i].crclist,list_known_crc[known_id]); 00270 results[i].err++; 00271 } 00272 if ((results[i].execs & ID_MATRIX) && 00273 (results[i].crcmatrix!=matrix_known_crc[known_id])) { 00274 ee_printf("[%u]ERROR! matrix crc 0x%04x - should be 0x%04x\n",i,results[i].crcmatrix,matrix_known_crc[known_id]); 00275 results[i].err++; 00276 } 00277 if ((results[i].execs & ID_STATE) && 00278 (results[i].crcstate!=state_known_crc[known_id])) { 00279 ee_printf("[%u]ERROR! state crc 0x%04x - should be 0x%04x\n",i,results[i].crcstate,state_known_crc[known_id]); 00280 results[i].err++; 00281 } 00282 total_errors+=results[i].err; 00283 } 00284 } 00285 total_errors+=check_data_types(); 00286 /* and report results */ 00287 ee_printf("CoreMark Size : %lu\n",(ee_u32)results[0].size); 00288 ee_printf("Total ticks : %lu\n",(ee_u32)total_time); 00289 #if HAS_FLOAT 00290 ee_printf("Total time (secs): %f\n",time_in_secs(total_time)); 00291 if (time_in_secs(total_time) > 0) 00292 ee_printf("Iterations/Sec : %f\n",default_num_contexts*results[0].iterations/time_in_secs(total_time)); 00293 #else 00294 ee_printf("Total time (secs): %d\n",time_in_secs(total_time)); 00295 if (time_in_secs(total_time) > 0) 00296 ee_printf("Iterations/Sec : %d\n",default_num_contexts*results[0].iterations/time_in_secs(total_time)); 00297 #endif 00298 if (time_in_secs(total_time) < 10) { 00299 ee_printf("ERROR! Must execute for at least 10 secs for a valid result!\n"); 00300 total_errors++; 00301 } 00302 00303 ee_printf("Iterations : %lu\n",(ee_u32)default_num_contexts*results[0].iterations); 00304 ee_printf("Compiler version : %s\n",COMPILER_VERSION); 00305 ee_printf("Compiler flags : %s\n",COMPILER_FLAGS); 00306 #if (MULTITHREAD>1) 00307 ee_printf("Parallel %s : %d\n",PARALLEL_METHOD,default_num_contexts); 00308 #endif 00309 ee_printf("Memory location : %s\n",MEM_LOCATION); 00310 /* output for verification */ 00311 ee_printf("seedcrc : 0x%04x\n",seedcrc); 00312 if (results[0].execs & ID_LIST) 00313 for (i=0 ; i<default_num_contexts; i++) 00314 ee_printf("[%d]crclist : 0x%04x\n",i,results[i].crclist); 00315 if (results[0].execs & ID_MATRIX) 00316 for (i=0 ; i<default_num_contexts; i++) 00317 ee_printf("[%d]crcmatrix : 0x%04x\n",i,results[i].crcmatrix); 00318 if (results[0].execs & ID_STATE) 00319 for (i=0 ; i<default_num_contexts; i++) 00320 ee_printf("[%d]crcstate : 0x%04x\n",i,results[i].crcstate); 00321 for (i=0 ; i<default_num_contexts; i++) 00322 ee_printf("[%d]crcfinal : 0x%04x\n",i,results[i].crc); 00323 if (total_errors==0) { 00324 ee_printf("Correct operation validated. See readme.txt for run and reporting rules.\n"); 00325 #if HAS_FLOAT 00326 if (known_id==3) { 00327 ee_printf("CoreMark 1.0 : %f / %s %s",default_num_contexts*results[0].iterations/time_in_secs(total_time),COMPILER_VERSION,COMPILER_FLAGS); 00328 #if defined(MEM_LOCATION) && !defined(MEM_LOCATION_UNSPEC) 00329 ee_printf(" / %s",MEM_LOCATION); 00330 #else 00331 ee_printf(" / %s",mem_name[MEM_METHOD]); 00332 #endif 00333 00334 #if (MULTITHREAD>1) 00335 ee_printf(" / %d:%s",default_num_contexts,PARALLEL_METHOD); 00336 #endif 00337 ee_printf("\n"); 00338 } 00339 #endif 00340 } 00341 if (total_errors>0) 00342 ee_printf("Errors detected\n"); 00343 if (total_errors<0) 00344 ee_printf("Cannot validate operation for these seed values, please compare with results on a known platform.\n"); 00345 00346 #if (MEM_METHOD==MEM_MALLOC) 00347 for (i=0 ; i<MULTITHREAD; i++) 00348 portable_free(results[i].memblock[0]); 00349 #endif 00350 /* And last call any target specific code for finalizing */ 00351 portable_fini(&(results[0].port)); 00352 00353 return MAIN_RETURN_VAL; 00354 } 00355 00356
Generated on Fri Jul 15 2022 12:36:20 by 1.7.2