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

Subversion Repositories openrisc

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

Go to most recent revision | 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
 
116
#if MAIN_HAS_NOARGC
117
MAIN_RETURN_TYPE coremark_main(void)
118
{
119
        int argc = 0;
120
        char *argv[1];
121
#else
122
MAIN_RETURN_TYPE coremark_main(int argc, char *argv[])
123
{
124
#endif
125
        ee_u16 i, j = 0, num_algorithms = 0;
126
        ee_s16 known_id = -1, total_errors = 0;
127
        ee_u16 seedcrc = 0;
128
        CORE_TICKS total_time;
129
        core_results results[MULTITHREAD];
130
#if (MEM_METHOD==MEM_STACK)
131
        ee_u8 stack_memblock[TOTAL_DATA_SIZE * MULTITHREAD];
132
#endif
133
        /* first call any initializations needed */
134
        portable_init(&(results[0].port), &argc, argv);
135
        /* First some checks to make sure benchmark will run ok */
136
        if (sizeof(struct list_head_s) > 128) {
137
                ee_printf("list_head structure too big for comparable data!\n");
138
                return MAIN_RETURN_VAL;
139
        }
140
        results[0].seed1 = get_seed(1);
141
        results[0].seed2 = get_seed(2);
142
        results[0].seed3 = get_seed(3);
143
        results[0].iterations = get_seed_32(4);
144
#if CORE_DEBUG
145
        results[0].iterations = 1;
146
#endif
147
        results[0].execs = get_seed_32(5);
148
        if (results[0].execs == 0) {
149
                /* if not supplied, execute all algorithms */
150
                results[0].execs = ALL_ALGORITHMS_MASK;
151
        }
152
        /* put in some default values based on one seed only for easy testing */
153
        if ((results[0].seed1 == 0) && (results[0].seed2 == 0)
154
            && (results[0].seed3 == 0)) { /* validation run */
155
                results[0].seed1 = 0;
156
                results[0].seed2 = 0;
157
                results[0].seed3 = 0x66;
158
        }
159
        if ((results[0].seed1 == 1) && (results[0].seed2 == 0)
160
            && (results[0].seed3 == 0)) { /* perfromance run */
161
                results[0].seed1 = 0x3415;
162
                results[0].seed2 = 0x3415;
163
                results[0].seed3 = 0x66;
164
        }
165
#if (MEM_METHOD==MEM_STATIC)
166
        results[0].memblock[0] = (void *)static_memblk;
167
        results[0].size = TOTAL_DATA_SIZE;
168
        results[0].err = 0;
169
#if (MULTITHREAD>1)
170
#error "Cannot use a static data area with multiple contexts!"
171
#endif
172
#elif (MEM_METHOD==MEM_MALLOC)
173
        for (i = 0; i < MULTITHREAD; i++) {
174
                ee_s32 malloc_override = get_seed(7);
175
                if (malloc_override != 0)
176
                        results[i].size = malloc_override;
177
                else
178
                        results[i].size = TOTAL_DATA_SIZE;
179
                results[i].memblock[0] = portable_malloc(results[i].size);
180
                results[i].seed1 = results[0].seed1;
181
                results[i].seed2 = results[0].seed2;
182
                results[i].seed3 = results[0].seed3;
183
                results[i].err = 0;
184
                results[i].execs = results[0].execs;
185
        }
186
#elif (MEM_METHOD==MEM_STACK)
187
        for (i = 0; i < MULTITHREAD; i++) {
188
                results[i].memblock[0] = stack_memblock + i * TOTAL_DATA_SIZE;
189
                results[i].size = TOTAL_DATA_SIZE;
190
                results[i].seed1 = results[0].seed1;
191
                results[i].seed2 = results[0].seed2;
192
                results[i].seed3 = results[0].seed3;
193
                results[i].err = 0;
194
                results[i].execs = results[0].execs;
195
        }
196
#else
197
#error "Please define a way to initialize a memory block."
198
#endif
199
        /* Data init */
200
        /* Find out how space much we have based on number of algorithms */
201
        for (i = 0; i < NUM_ALGORITHMS; i++) {
202
                if ((1 << (ee_u32) i) & results[0].execs)
203
                        num_algorithms++;
204
        }
205
        for (i = 0; i < MULTITHREAD; i++)
206
                results[i].size = results[i].size / num_algorithms;
207
        /* Assign pointers */
208
        for (i = 0; i < NUM_ALGORITHMS; i++) {
209
                ee_u32 ctx;
210
                if ((1 << (ee_u32) i) & results[0].execs) {
211
                        for (ctx = 0; ctx < MULTITHREAD; ctx++)
212
                                results[ctx].memblock[i + 1] =
213
                                    (char *)(results[ctx].memblock[0]) +
214
                                    results[0].size * j;
215
                        j++;
216
                }
217
        }
218
        /* call inits */
219
        for (i = 0; i < MULTITHREAD; i++) {
220
                if (results[i].execs & ID_LIST) {
221
                        results[i].list =
222
                            core_list_init(results[0].size,
223
                                           results[i].memblock[1],
224
                                           results[i].seed1);
225
                }
226
                if (results[i].execs & ID_MATRIX) {
227
                        core_init_matrix(results[0].size,
228
                                         results[i].memblock[2],
229
                                         (ee_s32) results[i].seed1 |
230
                                         (((ee_s32) results[i].seed2) << 16),
231
                                         &(results[i].mat));
232
                }
233
                if (results[i].execs & ID_STATE) {
234
                        core_init_state(results[0].size, results[i].seed1,
235
                                        results[i].memblock[3]);
236
                }
237
        }
238
 
239
        /* automatically determine number of iterations if not set */
240
        if (results[0].iterations == 0) {
241
                secs_ret secs_passed = 0;
242
                ee_u32 divisor;
243
                results[0].iterations = 1;
244
                while (secs_passed < (secs_ret) 1) {
245
                        results[0].iterations *= 10;
246
                        start_time();
247
                        iterate(&results[0]);
248
                        stop_time();
249
                        secs_passed = time_in_secs(get_time());
250
                }
251
                /* now we know it executes for at least 1 sec, set actual run
252
                   time at about 10 secs */
253
                divisor = (ee_u32) secs_passed;
254
                if (divisor == 0)        /* some machines cast float to int as 0
255
                                           since this conversion is not defined
256
                                           by ANSI, but we know at least one
257
                                           second passed */
258
                        divisor = 1;
259
                results[0].iterations *= 1 + 10 / divisor;
260
        }
261
        /* perform actual benchmark */
262
        start_time();
263
#if (MULTITHREAD>1)
264
        if (default_num_contexts > MULTITHREAD) {
265
                default_num_contexts = MULTITHREAD;
266
        }
267
        for (i = 0; i < default_num_contexts; i++) {
268
                results[i].iterations = results[0].iterations;
269
                results[i].execs = results[0].execs;
270
                core_start_parallel(&results[i]);
271
        }
272
        for (i = 0; i < default_num_contexts; i++) {
273
                core_stop_parallel(&results[i]);
274
        }
275
#else
276
        iterate(&results[0]);
277
#endif
278
        stop_time();
279
        total_time = get_time();
280
        /* get a function of the input to report */
281
        seedcrc = crc16(results[0].seed1, seedcrc);
282
        seedcrc = crc16(results[0].seed2, seedcrc);
283
        seedcrc = crc16(results[0].seed3, seedcrc);
284
        seedcrc = crc16(results[0].size, seedcrc);
285
 
286
        switch (seedcrc) {      /* test known output for common seeds */
287
        case 0x8a02:            /* seed1=0, seed2=0, seed3=0x66, size 2000 per
288
                                   algorithm */
289
                known_id = 0;
290
                ee_printf("6k performance run parameters for coremark.\n");
291
                break;
292
        case 0x7b05:            /*  seed1=0x3415, seed2=0x3415, seed3=0x66,
293
                                    size 2000 per algorithm */
294
                known_id = 1;
295
                ee_printf("6k validation run parameters for coremark.\n");
296
                break;
297
        case 0x4eaf:            /* seed1=0x8, seed2=0x8, seed3=0x8, size 400
298
                                   per algorithm */
299
                known_id = 2;
300
                ee_printf("Profile generation run parameters for coremark.\n");
301
                break;
302
        case 0xe9f5:            /* seed1=0, seed2=0, seed3=0x66, size 666 per
303
                                   algorithm */
304
                known_id = 3;
305
                ee_printf("2K performance run parameters for coremark.\n");
306
                break;
307
        case 0x18f2:            /*  seed1=0x3415, seed2=0x3415, seed3=0x66,
308
                                    size 666 per algorithm */
309
                known_id = 4;
310
                ee_printf("2K validation run parameters for coremark.\n");
311
                break;
312
        default:
313
                total_errors = -1;
314
                break;
315
        }
316
        if (known_id >= 0) {
317
                for (i = 0; i < default_num_contexts; i++) {
318
                        results[i].err = 0;
319
                        if ((results[i].execs & ID_LIST) &&
320
                            (results[i].crclist != list_known_crc[known_id])) {
321
                                ee_printf
322
                                    ("[%u]ERROR! list crc 0x%04x - should be 0x%04x\n",
323
                                     i, results[i].crclist,
324
                                     list_known_crc[known_id]);
325
                                results[i].err++;
326
                        }
327
                        if ((results[i].execs & ID_MATRIX) &&
328
                            (results[i].crcmatrix !=
329
                             matrix_known_crc[known_id])) {
330
                                ee_printf
331
                                    ("[%u]ERROR! matrix crc 0x%04x - should be 0x%04x\n",
332
                                     i, results[i].crcmatrix,
333
                                     matrix_known_crc[known_id]);
334
                                results[i].err++;
335
                        }
336
                        if ((results[i].execs & ID_STATE) &&
337
                            (results[i].crcstate != state_known_crc[known_id]))
338
                        {
339
                                ee_printf
340
                                    ("[%u]ERROR! state crc 0x%04x - should be 0x%04x\n",
341
                                     i, results[i].crcstate,
342
                                     state_known_crc[known_id]);
343
                                results[i].err++;
344
                        }
345
                        total_errors += results[i].err;
346
                }
347
        }
348
        total_errors += check_data_types();
349
        /* and report results */
350
        ee_printf("CoreMark Size    : %lu\n", (ee_u32) results[0].size);
351
        ee_printf("Total ticks      : %lu\n", (ee_u32) total_time);
352
#if HAS_FLOAT
353
        ee_printf("Total time (secs): %f\n", time_in_secs(total_time));
354
        if (time_in_secs(total_time) > 0)
355
                ee_printf("Iterations/Sec   : %f\n",
356
                          default_num_contexts * results[0].iterations /
357
                          time_in_secs(total_time));
358
#else
359
        ee_printf("Total time (secs): %d\n", time_in_secs(total_time));
360
        if (time_in_secs(total_time) > 0)
361
                ee_printf("Iterations/Sec   : %d\n",
362
                          default_num_contexts * results[0].iterations /
363
                          time_in_secs(total_time));
364
#endif
365
        if (time_in_secs(total_time) < 10) {
366
                ee_printf
367
                    ("ERROR! Must execute for at least 10 secs for a valid result!\n");
368
                total_errors++;
369
        }
370
 
371
        ee_printf("Iterations       : %lu\n",
372
                  (ee_u32) default_num_contexts * results[0].iterations);
373
        ee_printf("Compiler version : %s\n", COMPILER_VERSION);
374
        ee_printf("Compiler flags   : %s\n", COMPILER_FLAGS);
375
#if (MULTITHREAD>1)
376
        ee_printf("Parallel %s : %d\n", PARALLEL_METHOD, default_num_contexts);
377
#endif
378
        ee_printf("Memory location  : %s\n", MEM_LOCATION);
379
        /* output for verification */
380
        ee_printf("seedcrc          : 0x%04x\n", seedcrc);
381
        if (results[0].execs & ID_LIST)
382
                for (i = 0; i < default_num_contexts; i++)
383
                        ee_printf("[%d]crclist       : 0x%04x\n", i,
384
                                  results[i].crclist);
385
        if (results[0].execs & ID_MATRIX)
386
                for (i = 0; i < default_num_contexts; i++)
387
                        ee_printf("[%d]crcmatrix     : 0x%04x\n", i,
388
                                  results[i].crcmatrix);
389
        if (results[0].execs & ID_STATE)
390
                for (i = 0; i < default_num_contexts; i++)
391
                        ee_printf("[%d]crcstate      : 0x%04x\n", i,
392
                                  results[i].crcstate);
393
        for (i = 0; i < default_num_contexts; i++)
394
                ee_printf("[%d]crcfinal      : 0x%04x\n", i, results[i].crc);
395
        if (total_errors == 0) {
396
                ee_printf
397
                    ("Correct operation validated. See readme.txt for run and reporting rules.\n");
398
#if HAS_FLOAT
399
                if (known_id == 3) {
400
                        ee_printf("CoreMark 1.0 : %f / %s %s",
401
                                  default_num_contexts * results[0].iterations /
402
                                  time_in_secs(total_time), COMPILER_VERSION,
403
                                  COMPILER_FLAGS);
404
#if defined(MEM_LOCATION) && !defined(MEM_LOCATION_UNSPEC)
405
                        ee_printf(" / %s", MEM_LOCATION);
406
#else
407
                        ee_printf(" / %s", mem_name[MEM_METHOD]);
408
#endif
409
 
410
#if (MULTITHREAD>1)
411
                        ee_printf(" / %d:%s", default_num_contexts,
412
                                  PARALLEL_METHOD);
413
#endif
414
                        ee_printf("\n");
415
                }
416
#endif
417
        }
418
        if (total_errors > 0)
419
                ee_printf("Errors detected\n");
420
        if (total_errors < 0)
421
                ee_printf
422
                    ("Cannot validate operation for these seed values, please compare with results on a known platform.\n");
423
 
424
#if (MEM_METHOD==MEM_MALLOC)
425
        for (i = 0; i < MULTITHREAD; i++)
426
                portable_free(results[i].memblock[0]);
427
#endif
428
        /* And last call any target specific code for finalizing */
429
        portable_fini(&(results[0].port));
430
 
431
        return MAIN_RETURN_VAL;
432
}
433
 
434
 
435
 
436
int coremark_cmd (int argc, char *argv[])
437
{
438
  return coremark_main(argc, argv);
439
 
440
}
441
 
442
void module_coremark_init (void)
443
{
444
  register_command ("coremark", "[<mode>] [<iterations>]",
445
          "run coremark, mode: p - performance run, o - profile run, default - validation run",
446
                    coremark_cmd);
447
}

powered by: WebSVN 2.1.0

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