OpenCores
URL https://opencores.org/ocsvn/openmsp430/openmsp430/trunk

Subversion Repositories openmsp430

[/] [openmsp430/] [trunk/] [core/] [sim/] [rtl_sim/] [src-c/] [coremark_v1.0/] [core_main.c] - Blame information for rev 178

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 145 olivier.gi
/*
2
Author : Shay Gal-On, EEMBC
3
 
4
This file is part of  EEMBC(R) and CoreMark(TM), which are Copyright (C) 2009
5
All rights reserved.
6
 
7
EEMBC CoreMark Software is a product of EEMBC and is provided under the terms of the
8
CoreMark License that is distributed with the official EEMBC COREMARK Software release.
9
If you received this EEMBC CoreMark Software without the accompanying CoreMark License,
10
you must discontinue use and download the official release from www.coremark.org.
11
 
12
Also, if you are publicly displaying scores generated from the EEMBC CoreMark software,
13
make sure that you are in compliance with Run and Reporting rules specified in the accompanying readme.txt file.
14
 
15
EEMBC
16
4354 Town Center Blvd. Suite 114-200
17
El 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
*/
35
static ee_u16 list_known_crc[]   =      {(ee_u16)0xd4b0,(ee_u16)0x3340,(ee_u16)0x6a79,(ee_u16)0xe714,(ee_u16)0xe3c1};
36
static ee_u16 matrix_known_crc[] =      {(ee_u16)0xbe52,(ee_u16)0x1199,(ee_u16)0x5608,(ee_u16)0x1fd7,(ee_u16)0x0747};
37
static ee_u16 state_known_crc[]  =      {(ee_u16)0x5e47,(ee_u16)0x39bf,(ee_u16)0xe5a4,(ee_u16)0x8e3a,(ee_u16)0x8d84};
38
void *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)
59
ee_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 */
63
ee_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)
68
ee_u8 static_memblk[TOTAL_DATA_SIZE];
69
#endif
70
char *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
89
MAIN_RETURN_TYPE main(void) {
90
        int argc=0;
91
        char *argv[1];
92
#else
93
MAIN_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
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.