source: soft/giet_vm/applications/coremark/core_main.c

Last change on this file was 753, checked in by cfuguet, 9 years ago

Introducing the coremark benchmark

File size: 12.2 KB
Line 
1/*
2Author : Shay Gal-On, EEMBC
3
4This file is part of  EEMBC(R) and CoreMark(TM), which are Copyright (C) 2009
5All rights reserved.                           
6
7EEMBC CoreMark Software is a product of EEMBC and is provided under the terms of the
8CoreMark License that is distributed with the official EEMBC COREMARK Software release.
9If you received this EEMBC CoreMark Software without the accompanying CoreMark License,
10you must discontinue use and download the official release from www.coremark.org. 
11
12Also, if you are publicly displaying scores generated from the EEMBC CoreMark software,
13make sure that you are in compliance with Run and Reporting rules specified in the accompanying readme.txt file.
14
15EEMBC
164354 Town Center Blvd. Suite 114-200
17El Dorado Hills, CA, 95762
18*/ 
19/* File: core_main.c
20        This file contains the framework to acquire a block of memory, seed initial parameters, tun t he benchmark and report the results.
21*/
22#include "coremark.h"
23
24/* Function: iterate
25        Run the benchmark for a specified number of iterations.
26
27        Operation:
28        For each type of benchmarked algorithm:
29                a - Initialize the data block for the algorithm.
30                b - Execute the algorithm N times.
31
32        Returns:
33        NULL.
34*/
35static ee_u16 list_known_crc[]   =      {(ee_u16)0xd4b0,(ee_u16)0x3340,(ee_u16)0x6a79,(ee_u16)0xe714,(ee_u16)0xe3c1};
36static ee_u16 matrix_known_crc[] =      {(ee_u16)0xbe52,(ee_u16)0x1199,(ee_u16)0x5608,(ee_u16)0x1fd7,(ee_u16)0x0747};
37static ee_u16 state_known_crc[]  =      {(ee_u16)0x5e47,(ee_u16)0x39bf,(ee_u16)0xe5a4,(ee_u16)0x8e3a,(ee_u16)0x8d84};
38void *iterate(void *pres) {
39        ee_u32 i;
40        ee_u16 crc;
41        core_results *res=(core_results *)pres;
42        ee_u32 iterations=res->iterations;
43        res->crc=0;
44        res->crclist=0;
45        res->crcmatrix=0;
46        res->crcstate=0;
47
48        for (i=0; i<iterations; i++) {
49                crc=core_bench_list(res,1);
50                res->crc=crcu16(crc,res->crc);
51                crc=core_bench_list(res,-1);
52                res->crc=crcu16(crc,res->crc);
53                if (i==0) res->crclist=res->crc;
54        }
55        return NULL;
56}
57
58#if (SEED_METHOD==SEED_ARG)
59ee_s32 get_seed_args(int i, int argc, char *argv[]);
60#define get_seed(x) (ee_s16)get_seed_args(x,argc,argv)
61#define get_seed_32(x) get_seed_args(x,argc,argv)
62#else /* via function or volatile */
63ee_s32 get_seed_32(int i);
64#define get_seed(x) (ee_s16)get_seed_32(x)
65#endif
66
67#if (MEM_METHOD==MEM_STATIC)
68ee_u8 static_memblk[TOTAL_DATA_SIZE];
69#endif
70char *mem_name[3] = {"Static","Heap","Stack"};
71/* Function: main
72        Main entry routine for the benchmark.
73        This function is responsible for the following steps:
74
75        1 - Initialize input seeds from a source that cannot be determined at compile time.
76        2 - Initialize memory block for use.
77        3 - Run and time the benchmark.
78        4 - Report results, testing the validity of the output if the seeds are known.
79
80        Arguments:
81        1 - first seed  : Any value
82        2 - second seed : Must be identical to first for iterations to be identical
83        3 - third seed  : Any value, should be at least an order of magnitude less then the input size, but bigger then 32.
84        4 - Iterations  : Special, if set to 0, iterations will be automatically determined such that the benchmark will run between 10 to 100 secs
85
86*/
87
88#if MAIN_HAS_NOARGC
89MAIN_RETURN_TYPE main(void) {
90        int argc=0;
91        char *argv[1];
92#else
93MAIN_RETURN_TYPE main(int argc, char *argv[]) {
94#endif
95        ee_u16 i,j=0,num_algorithms=0;
96        ee_s16 known_id=-1,total_errors=0;
97        ee_u16 seedcrc=0;
98        CORE_TICKS total_time;
99        core_results results[MULTITHREAD];
100#if (MEM_METHOD==MEM_STACK)
101        ee_u8 stack_memblock[TOTAL_DATA_SIZE*MULTITHREAD];
102#endif
103        /* first call any initializations needed */
104        portable_init(&(results[0].port), &argc, argv);
105        /* First some checks to make sure benchmark will run ok */
106        if (sizeof(struct list_head_s)>128) {
107                ee_printf("list_head structure too big for comparable data!\n");
108                return MAIN_RETURN_VAL;
109        }
110        results[0].seed1=get_seed(1);
111        results[0].seed2=get_seed(2);
112        results[0].seed3=get_seed(3);
113        results[0].iterations=get_seed_32(4);
114#if CORE_DEBUG
115        results[0].iterations=1;
116#endif
117        results[0].execs=get_seed_32(5);
118        if (results[0].execs==0) { /* if not supplied, execute all algorithms */
119                results[0].execs=ALL_ALGORITHMS_MASK;
120        }
121                /* put in some default values based on one seed only for easy testing */
122        if ((results[0].seed1==0) && (results[0].seed2==0) && (results[0].seed3==0)) { /* validation run */
123                results[0].seed1=0;
124                results[0].seed2=0;
125                results[0].seed3=0x66;
126        }
127        if ((results[0].seed1==1) && (results[0].seed2==0) && (results[0].seed3==0)) { /* perfromance run */
128                results[0].seed1=0x3415;
129                results[0].seed2=0x3415;
130                results[0].seed3=0x66;
131        }
132#if (MEM_METHOD==MEM_STATIC)
133        results[0].memblock[0]=(void *)static_memblk;
134        results[0].size=TOTAL_DATA_SIZE;
135        results[0].err=0;
136        #if (MULTITHREAD>1)
137        #error "Cannot use a static data area with multiple contexts!"
138        #endif
139#elif (MEM_METHOD==MEM_MALLOC)
140        for (i=0 ; i<MULTITHREAD; i++) {
141                ee_s32 malloc_override=get_seed(7);
142                if (malloc_override != 0) 
143                        results[i].size=malloc_override;
144                else
145                        results[i].size=TOTAL_DATA_SIZE;
146                results[i].memblock[0]=portable_malloc(results[i].size);
147                results[i].seed1=results[0].seed1;
148                results[i].seed2=results[0].seed2;
149                results[i].seed3=results[0].seed3;
150                results[i].err=0;
151                results[i].execs=results[0].execs;
152        }
153#elif (MEM_METHOD==MEM_STACK)
154        for (i=0 ; i<MULTITHREAD; i++) {
155                results[i].memblock[0]=stack_memblock+i*TOTAL_DATA_SIZE;
156                results[i].size=TOTAL_DATA_SIZE;
157                results[i].seed1=results[0].seed1;
158                results[i].seed2=results[0].seed2;
159                results[i].seed3=results[0].seed3;
160                results[i].err=0;
161                results[i].execs=results[0].execs;
162        }
163#else
164#error "Please define a way to initialize a memory block."
165#endif
166        /* Data init */ 
167        /* Find out how space much we have based on number of algorithms */
168        for (i=0; i<NUM_ALGORITHMS; i++) {
169                if ((1<<(ee_u32)i) & results[0].execs)
170                        num_algorithms++;
171        }
172        for (i=0 ; i<MULTITHREAD; i++) 
173                results[i].size=results[i].size/num_algorithms;
174        /* Assign pointers */
175        for (i=0; i<NUM_ALGORITHMS; i++) {
176                ee_u32 ctx;
177                if ((1<<(ee_u32)i) & results[0].execs) {
178                        for (ctx=0 ; ctx<MULTITHREAD; ctx++)
179                                results[ctx].memblock[i+1]=(char *)(results[ctx].memblock[0])+results[0].size*j;
180                        j++;
181                }
182        }
183        /* call inits */
184        for (i=0 ; i<MULTITHREAD; i++) {
185                if (results[i].execs & ID_LIST) {
186                        results[i].list=core_list_init(results[0].size,results[i].memblock[1],results[i].seed1);
187                }
188                if (results[i].execs & ID_MATRIX) {
189                        core_init_matrix(results[0].size, results[i].memblock[2], (ee_s32)results[i].seed1 | (((ee_s32)results[i].seed2) << 16), &(results[i].mat) );
190                }
191                if (results[i].execs & ID_STATE) {
192                        core_init_state(results[0].size,results[i].seed1,results[i].memblock[3]);
193                }
194        }
195       
196        /* automatically determine number of iterations if not set */
197        if (results[0].iterations==0) { 
198                secs_ret secs_passed=0;
199                ee_u32 divisor;
200                results[0].iterations=1;
201                while (secs_passed < (secs_ret)1) {
202                        results[0].iterations*=10;
203                        start_time();
204                        iterate(&results[0]);
205                        stop_time();
206                        secs_passed=time_in_secs(get_time());
207                }
208                /* now we know it executes for at least 1 sec, set actual run time at about 10 secs */
209                divisor=(ee_u32)secs_passed;
210                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 */
211                        divisor=1;
212                results[0].iterations*=1+10/divisor;
213        }
214        /* perform actual benchmark */
215        start_time();
216#if (MULTITHREAD>1)
217        if (default_num_contexts>MULTITHREAD) {
218                default_num_contexts=MULTITHREAD;
219        }
220        for (i=0 ; i<default_num_contexts; i++) {
221                results[i].iterations=results[0].iterations;
222                results[i].execs=results[0].execs;
223                core_start_parallel(&results[i]);
224        }
225        for (i=0 ; i<default_num_contexts; i++) {
226                core_stop_parallel(&results[i]);
227        }
228#else
229        iterate(&results[0]);
230#endif
231        stop_time();
232        total_time=get_time();
233        /* get a function of the input to report */
234        seedcrc=crc16(results[0].seed1,seedcrc);
235        seedcrc=crc16(results[0].seed2,seedcrc);
236        seedcrc=crc16(results[0].seed3,seedcrc);
237        seedcrc=crc16(results[0].size,seedcrc);
238       
239        switch (seedcrc) { /* test known output for common seeds */
240                case 0x8a02: /* seed1=0, seed2=0, seed3=0x66, size 2000 per algorithm */
241                        known_id=0;
242                        ee_printf("6k performance run parameters for coremark.\n");
243                        break;
244                case 0x7b05: /*  seed1=0x3415, seed2=0x3415, seed3=0x66, size 2000 per algorithm */
245                        known_id=1;
246                        ee_printf("6k validation run parameters for coremark.\n");
247                        break;
248                case 0x4eaf: /* seed1=0x8, seed2=0x8, seed3=0x8, size 400 per algorithm */
249                        known_id=2;
250                        ee_printf("Profile generation run parameters for coremark.\n");
251                        break;
252                case 0xe9f5: /* seed1=0, seed2=0, seed3=0x66, size 666 per algorithm */
253                        known_id=3;
254                        ee_printf("2K performance run parameters for coremark.\n");
255                        break;
256                case 0x18f2: /*  seed1=0x3415, seed2=0x3415, seed3=0x66, size 666 per algorithm */
257                        known_id=4;
258                        ee_printf("2K validation run parameters for coremark.\n");
259                        break;
260                default:
261                        total_errors=-1;
262                        break;
263        }
264        if (known_id>=0) {
265                for (i=0 ; i<default_num_contexts; i++) {
266                        results[i].err=0;
267                        if ((results[i].execs & ID_LIST) && 
268                                (results[i].crclist!=list_known_crc[known_id])) {
269                                ee_printf("[%u]ERROR! list crc 0x%04x - should be 0x%04x\n",i,results[i].crclist,list_known_crc[known_id]);
270                                results[i].err++;
271                        }
272                        if ((results[i].execs & ID_MATRIX) &&
273                                (results[i].crcmatrix!=matrix_known_crc[known_id])) {
274                                ee_printf("[%u]ERROR! matrix crc 0x%04x - should be 0x%04x\n",i,results[i].crcmatrix,matrix_known_crc[known_id]);
275                                results[i].err++;
276                        }
277                        if ((results[i].execs & ID_STATE) &&
278                                (results[i].crcstate!=state_known_crc[known_id])) {
279                                ee_printf("[%u]ERROR! state crc 0x%04x - should be 0x%04x\n",i,results[i].crcstate,state_known_crc[known_id]);
280                                results[i].err++;
281                        }
282                        total_errors+=results[i].err;
283                }
284        }
285        total_errors+=check_data_types();
286        /* and report results */
287        ee_printf("CoreMark Size    : %lu\n",(ee_u32)results[0].size);
288        ee_printf("Total ticks      : %lu\n",(ee_u32)total_time);
289#if HAS_FLOAT
290        ee_printf("Total time (secs): %f\n",time_in_secs(total_time));
291        if (time_in_secs(total_time) > 0)
292                ee_printf("Iterations/Sec   : %f\n",default_num_contexts*results[0].iterations/time_in_secs(total_time));
293#else
294        ee_printf("Total time (secs): %d\n",time_in_secs(total_time));
295        if (time_in_secs(total_time) > 0)
296                ee_printf("Iterations/Sec   : %d\n",default_num_contexts*results[0].iterations/time_in_secs(total_time));
297#endif
298        if (time_in_secs(total_time) < 10) {
299                ee_printf("ERROR! Must execute for at least 10 secs for a valid result!\n");
300                total_errors++;
301        }
302
303        ee_printf("Iterations       : %lu\n",(ee_u32)default_num_contexts*results[0].iterations);
304        ee_printf("Compiler version : %s\n",COMPILER_VERSION);
305        ee_printf("Compiler flags   : %s\n",COMPILER_FLAGS);
306#if (MULTITHREAD>1)
307        ee_printf("Parallel %s : %d\n",PARALLEL_METHOD,default_num_contexts);
308#endif
309        ee_printf("Memory location  : %s\n",MEM_LOCATION);
310        /* output for verification */
311        ee_printf("seedcrc          : 0x%04x\n",seedcrc);
312        if (results[0].execs & ID_LIST)
313                for (i=0 ; i<default_num_contexts; i++) 
314                        ee_printf("[%d]crclist       : 0x%04x\n",i,results[i].crclist);
315        if (results[0].execs & ID_MATRIX) 
316                for (i=0 ; i<default_num_contexts; i++) 
317                        ee_printf("[%d]crcmatrix     : 0x%04x\n",i,results[i].crcmatrix);
318        if (results[0].execs & ID_STATE)
319                for (i=0 ; i<default_num_contexts; i++) 
320                        ee_printf("[%d]crcstate      : 0x%04x\n",i,results[i].crcstate);
321        for (i=0 ; i<default_num_contexts; i++) 
322                ee_printf("[%d]crcfinal      : 0x%04x\n",i,results[i].crc);
323        if (total_errors==0) {
324                ee_printf("Correct operation validated. See readme.txt for run and reporting rules.\n");
325#if HAS_FLOAT
326                if (known_id==3) {
327                        ee_printf("CoreMark 1.0 : %f / %s %s",default_num_contexts*results[0].iterations/time_in_secs(total_time),COMPILER_VERSION,COMPILER_FLAGS);
328#if defined(MEM_LOCATION) && !defined(MEM_LOCATION_UNSPEC)
329                        ee_printf(" / %s",MEM_LOCATION);
330#else
331                        ee_printf(" / %s",mem_name[MEM_METHOD]);
332#endif
333
334#if (MULTITHREAD>1)
335                        ee_printf(" / %d:%s",default_num_contexts,PARALLEL_METHOD);
336#endif
337                        ee_printf("\n");
338                }
339#endif
340        }
341        if (total_errors>0)
342                ee_printf("Errors detected\n");
343        if (total_errors<0)
344                ee_printf("Cannot validate operation for these seed values, please compare with results on a known platform.\n");
345
346#if (MEM_METHOD==MEM_MALLOC)
347        for (i=0 ; i<MULTITHREAD; i++) 
348                portable_free(results[i].memblock[0]);
349#endif
350        /* And last call any target specific code for finalizing */
351        portable_fini(&(results[0].port));
352
353        return MAIN_RETURN_VAL; 
354}
355
356
Note: See TracBrowser for help on using the repository browser.