SAMV71 Xplained Ultra Software Package 1.3

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 main(void) {
00090     int argc=0;
00091     char *argv[1];
00092 #else
00093 MAIN_RETURN_TYPE main(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<32; i++) {
00169         if ((1<<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<32; i++) {
00176         ee_u32 ctx;
00177         if ((1<<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,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,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         void *retval;
00227         core_stop_parallel(&results[i]);
00228     }
00229 #else
00230     iterate(&results[0]);
00231 #endif
00232     stop_time();
00233     total_time=get_time();
00234     /* get a function of the input to report */
00235     seedcrc=crc16(results[0].seed1,seedcrc);
00236     seedcrc=crc16(results[0].seed2,seedcrc);
00237     seedcrc=crc16(results[0].seed3,seedcrc);
00238     seedcrc=crc16(results[0].size,seedcrc);
00239     
00240     switch (seedcrc) { /* test known output for common seeds */
00241         case 0x8a02: /* seed1=0, seed2=0, seed3=0x66, size 2000 per algorithm */
00242             known_id=0;
00243             ee_printf("6k performance run parameters for coremark.\n");
00244             break;
00245         case 0x7b05: /*  seed1=0x3415, seed2=0x3415, seed3=0x66, size 2000 per algorithm */
00246             known_id=1;
00247             ee_printf("6k validation run parameters for coremark.\n");
00248             break;
00249         case 0x4eaf: /* seed1=0x8, seed2=0x8, seed3=0x8, size 400 per algorithm */
00250             known_id=2;
00251             ee_printf("Profile generation run parameters for coremark.\n");
00252             break;
00253         case 0xe9f5: /* seed1=0, seed2=0, seed3=0x66, size 666 per algorithm */
00254             known_id=3;
00255             ee_printf("2K performance run parameters for coremark.\n");
00256             break;
00257         case 0x18f2: /*  seed1=0x3415, seed2=0x3415, seed3=0x66, size 666 per algorithm */
00258             known_id=4;
00259             ee_printf("2K validation run parameters for coremark.\n");
00260             break;
00261         default:
00262             total_errors=-1;
00263             break;
00264     }
00265     if (known_id>=0) {
00266         for (i=0 ; i<default_num_contexts; i++) {
00267             results[i].err=0;
00268             if ((results[i].execs & ID_LIST) && 
00269                 (results[i].crclist!=list_known_crc[known_id])) {
00270                 ee_printf("[%u]ERROR! list crc 0x%04x - should be 0x%04x\n",i,results[i].crclist,list_known_crc[known_id]);
00271                 results[i].err++;
00272             }
00273             if ((results[i].execs & ID_MATRIX) &&
00274                 (results[i].crcmatrix!=matrix_known_crc[known_id])) {
00275                 ee_printf("[%u]ERROR! matrix crc 0x%04x - should be 0x%04x\n",i,results[i].crcmatrix,matrix_known_crc[known_id]);
00276                 results[i].err++;
00277             }
00278             if ((results[i].execs & ID_STATE) &&
00279                 (results[i].crcstate!=state_known_crc[known_id])) {
00280                 ee_printf("[%u]ERROR! state crc 0x%04x - should be 0x%04x\n",i,results[i].crcstate,state_known_crc[known_id]);
00281                 results[i].err++;
00282             }
00283             total_errors+=results[i].err;
00284         }
00285     }
00286     /* and report results */
00287     ee_printf("CoreMark Size    : %d \n",(ee_u32)results[0].size);
00288     ee_printf("Total ticks      : %d \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         //ee_printf("default_num_contexts   : %d\n",default_num_contexts);
00298 #endif
00299     if (time_in_secs(total_time) < 10) {
00300         ee_printf("ERROR! Must execute for at least 10 secs for a valid result!\n");
00301         total_errors++;
00302     }
00303 
00304     ee_printf("Iterations       : %d\n",(ee_u32)default_num_contexts*results[0].iterations);
00305     ee_printf("Compiler version : %s\n",COMPILER_VERSION);
00306     ee_printf("Compiler flags   : %s\n",COMPILER_FLAGS);
00307 #if (MULTITHREAD>1)
00308     ee_printf("Parallel %s : %d\n",PARALLEL_METHOD,default_num_contexts);
00309 #endif
00310     ee_printf("Memory location  : %s\n",MEM_LOCATION);
00311     /* output for verification */
00312     ee_printf("seedcrc          : 0x%04x\n",seedcrc);
00313     if (results[0].execs & ID_LIST)
00314         for (i=0 ; i<default_num_contexts; i++) 
00315             ee_printf("[%d]crclist       : 0x%04x\n",i,results[i].crclist);
00316     if (results[0].execs & ID_MATRIX) 
00317         for (i=0 ; i<default_num_contexts; i++) 
00318             ee_printf("[%d]crcmatrix     : 0x%04x\n",i,results[i].crcmatrix);
00319     if (results[0].execs & ID_STATE)
00320         for (i=0 ; i<default_num_contexts; i++) 
00321             ee_printf("[%d]crcstate      : 0x%04x\n",i,results[i].crcstate);
00322     for (i=0 ; i<default_num_contexts; i++) 
00323         ee_printf("[%d]crcfinal      : 0x%04x\n",i,results[i].crc);
00324     if (total_errors==0) {
00325         ee_printf("Correct operation validated. See readme.txt for run and reporting rules.\n");
00326 #if HAS_FLOAT
00327         if (known_id==3) {
00328             ee_printf("CoreMark 1.0 : %f / %s %s",default_num_contexts*results[0].iterations/time_in_secs(total_time),COMPILER_VERSION,COMPILER_FLAGS);
00329 #if defined(MEM_LOCATION) && !defined(MEM_LOCATION_UNSPEC)
00330             ee_printf(" / %s",MEM_LOCATION);
00331 #else
00332             ee_printf(" / %s",mem_name[MEM_METHOD]);
00333 #endif
00334 
00335 #if (MULTITHREAD>1)
00336             ee_printf(" / %d:%s",MULTITHREAD,PARALLEL_METHOD);
00337 #endif
00338             ee_printf("\n");
00339         }
00340 #endif
00341     }
00342     if (total_errors>0)
00343         ee_printf("Errors detected\n");
00344     if (total_errors<0)
00345         ee_printf("Cannot validate operation for these seed values, please compare with results on a known platform.\n");
00346 
00347 #if (MEM_METHOD==MEM_MALLOC)
00348     for (i=0 ; i<MULTITHREAD; i++) 
00349         portable_free(results[i].memblock[0]);
00350 #endif
00351     /* And last call any target specific code for finalizing */
00352     portable_fini(&(results[0].port));
00353 
00354     return MAIN_RETURN_VAL; 
00355 }
00356 
00357 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines