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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [bootloaders/] [orpmon/] [coremark/] [core_main.c] - Blame information for rev 406

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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