mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Downloaded clean version of Coremark from EEMBC github page with which to benchmark RISCV-Wally
This commit is contained in:
parent
90eb84cc61
commit
d71b99383f
@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
CoreMark's primary goals are simplicity and providing a method for testing only a processor's core features. For more information about EEMBC's comprehensive embedded benchmark suites, please see www.eembc.org.
|
CoreMark's primary goals are simplicity and providing a method for testing only a processor's core features. For more information about EEMBC's comprehensive embedded benchmark suites, please see www.eembc.org.
|
||||||
|
|
||||||
|
For a more compute-intensive version of CoreMark that uses larger datasets and execution loops taken from common applications, please check out EEMBC's [CoreMark-PRO](https://www.github.com/eembc/coremark-pro) benchmark, also on GitHub.
|
||||||
|
|
||||||
# Building and Running
|
# Building and Running
|
||||||
|
|
||||||
To build and run the benchmark, type
|
To build and run the benchmark, type
|
||||||
@ -83,7 +85,9 @@ Use `XCFLAGS=-DMULTITHREAD=N` where N is number of threads to run in parallel. S
|
|||||||
% make XCFLAGS="-DMULTITHREAD=4 -DUSE_PTHREAD"
|
% make XCFLAGS="-DMULTITHREAD=4 -DUSE_PTHREAD"
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
Above will compile the benchmark for execution on 4 cores, using POSIX Threads API.
|
The above will compile the benchmark for execution on 4 cores, using POSIX Threads API.
|
||||||
|
|
||||||
|
Note: linking may fail on the previous command if your linker does not automatically add the `pthread` library. If you encounter `undefined reference` errors, please modify the `core_portme.mak` file for your platform, (e.g. `linux/core_portme.mak`) and add `-lpthread` to the `LFLAGS_END` parameter.
|
||||||
|
|
||||||
# Run Parameters for the Benchmark Executable
|
# Run Parameters for the Benchmark Executable
|
||||||
CoreMark's executable takes several parameters as follows (but only if `main()` accepts arguments):
|
CoreMark's executable takes several parameters as follows (but only if `main()` accepts arguments):
|
||||||
@ -109,7 +113,7 @@ The default for such a target when testing different configurations could be:
|
|||||||
|
|
||||||
# Submitting Results
|
# Submitting Results
|
||||||
|
|
||||||
CoreMark results can be submitted on the web. Open a web browser and go to https://www.eembc.org/coremark/login.php?url=enter_score.php. After registering an account you may enter a score.
|
CoreMark results can be submitted on the web. Open a web browser and go to the [submission page](https://www.eembc.org/coremark/submit.php). After registering an account you may enter a score.
|
||||||
|
|
||||||
# Run Rules
|
# Run Rules
|
||||||
What is and is not allowed.
|
What is and is not allowed.
|
||||||
|
159
riscv-coremark/coremark/barebones/core_portme.c
Executable file → Normal file
159
riscv-coremark/coremark/barebones/core_portme.c
Executable file → Normal file
@ -19,110 +19,135 @@ Original Author: Shay Gal-on
|
|||||||
#include "core_portme.h"
|
#include "core_portme.h"
|
||||||
|
|
||||||
#if VALIDATION_RUN
|
#if VALIDATION_RUN
|
||||||
volatile ee_s32 seed1_volatile=0x3415;
|
volatile ee_s32 seed1_volatile = 0x3415;
|
||||||
volatile ee_s32 seed2_volatile=0x3415;
|
volatile ee_s32 seed2_volatile = 0x3415;
|
||||||
volatile ee_s32 seed3_volatile=0x66;
|
volatile ee_s32 seed3_volatile = 0x66;
|
||||||
#endif
|
#endif
|
||||||
#if PERFORMANCE_RUN
|
#if PERFORMANCE_RUN
|
||||||
volatile ee_s32 seed1_volatile=0x0;
|
volatile ee_s32 seed1_volatile = 0x0;
|
||||||
volatile ee_s32 seed2_volatile=0x0;
|
volatile ee_s32 seed2_volatile = 0x0;
|
||||||
volatile ee_s32 seed3_volatile=0x66;
|
volatile ee_s32 seed3_volatile = 0x66;
|
||||||
#endif
|
#endif
|
||||||
#if PROFILE_RUN
|
#if PROFILE_RUN
|
||||||
volatile ee_s32 seed1_volatile=0x8;
|
volatile ee_s32 seed1_volatile = 0x8;
|
||||||
volatile ee_s32 seed2_volatile=0x8;
|
volatile ee_s32 seed2_volatile = 0x8;
|
||||||
volatile ee_s32 seed3_volatile=0x8;
|
volatile ee_s32 seed3_volatile = 0x8;
|
||||||
#endif
|
#endif
|
||||||
volatile ee_s32 seed4_volatile=ITERATIONS;
|
volatile ee_s32 seed4_volatile = ITERATIONS;
|
||||||
volatile ee_s32 seed5_volatile=0;
|
volatile ee_s32 seed5_volatile = 0;
|
||||||
/* Porting : Timing functions
|
/* Porting : Timing functions
|
||||||
How to capture time and convert to seconds must be ported to whatever is supported by the platform.
|
How to capture time and convert to seconds must be ported to whatever is
|
||||||
e.g. Read value from on board RTC, read value from cpu clock cycles performance counter etc.
|
supported by the platform. e.g. Read value from on board RTC, read value from
|
||||||
Sample implementation for standard time.h and windows.h definitions included.
|
cpu clock cycles performance counter etc. Sample implementation for standard
|
||||||
|
time.h and windows.h definitions included.
|
||||||
*/
|
*/
|
||||||
CORETIMETYPE barebones_clock() {
|
CORETIMETYPE
|
||||||
#error "You must implement a method to measure time in barebones_clock()! This function should return current time.\n"
|
barebones_clock()
|
||||||
|
{
|
||||||
|
#error \
|
||||||
|
"You must implement a method to measure time in barebones_clock()! This function should return current time.\n"
|
||||||
}
|
}
|
||||||
/* Define : TIMER_RES_DIVIDER
|
/* Define : TIMER_RES_DIVIDER
|
||||||
Divider to trade off timer resolution and total time that can be measured.
|
Divider to trade off timer resolution and total time that can be
|
||||||
|
measured.
|
||||||
|
|
||||||
Use lower values to increase resolution, but make sure that overflow does not occur.
|
Use lower values to increase resolution, but make sure that overflow
|
||||||
If there are issues with the return value overflowing, increase this value.
|
does not occur. If there are issues with the return value overflowing,
|
||||||
*/
|
increase this value.
|
||||||
#define GETMYTIME(_t) (*_t=barebones_clock())
|
*/
|
||||||
#define MYTIMEDIFF(fin,ini) ((fin)-(ini))
|
#define GETMYTIME(_t) (*_t = barebones_clock())
|
||||||
#define TIMER_RES_DIVIDER 1
|
#define MYTIMEDIFF(fin, ini) ((fin) - (ini))
|
||||||
|
#define TIMER_RES_DIVIDER 1
|
||||||
#define SAMPLE_TIME_IMPLEMENTATION 1
|
#define SAMPLE_TIME_IMPLEMENTATION 1
|
||||||
#define EE_TICKS_PER_SEC (CLOCKS_PER_SEC / TIMER_RES_DIVIDER)
|
#define EE_TICKS_PER_SEC (CLOCKS_PER_SEC / TIMER_RES_DIVIDER)
|
||||||
|
|
||||||
/** Define Host specific (POSIX), or target specific global time variables. */
|
/** Define Host specific (POSIX), or target specific global time variables. */
|
||||||
static CORETIMETYPE start_time_val, stop_time_val;
|
static CORETIMETYPE start_time_val, stop_time_val;
|
||||||
|
|
||||||
/* Function : start_time
|
/* Function : start_time
|
||||||
This function will be called right before starting the timed portion of the benchmark.
|
This function will be called right before starting the timed portion of
|
||||||
|
the benchmark.
|
||||||
|
|
||||||
Implementation may be capturing a system timer (as implemented in the example code)
|
Implementation may be capturing a system timer (as implemented in the
|
||||||
or zeroing some system parameters - e.g. setting the cpu clocks cycles to 0.
|
example code) or zeroing some system parameters - e.g. setting the cpu clocks
|
||||||
|
cycles to 0.
|
||||||
*/
|
*/
|
||||||
void start_time(void) {
|
void
|
||||||
GETMYTIME(&start_time_val );
|
start_time(void)
|
||||||
|
{
|
||||||
|
GETMYTIME(&start_time_val);
|
||||||
}
|
}
|
||||||
/* Function : stop_time
|
/* Function : stop_time
|
||||||
This function will be called right after ending the timed portion of the benchmark.
|
This function will be called right after ending the timed portion of the
|
||||||
|
benchmark.
|
||||||
|
|
||||||
Implementation may be capturing a system timer (as implemented in the example code)
|
Implementation may be capturing a system timer (as implemented in the
|
||||||
or other system parameters - e.g. reading the current value of cpu cycles counter.
|
example code) or other system parameters - e.g. reading the current value of
|
||||||
|
cpu cycles counter.
|
||||||
*/
|
*/
|
||||||
void stop_time(void) {
|
void
|
||||||
GETMYTIME(&stop_time_val );
|
stop_time(void)
|
||||||
|
{
|
||||||
|
GETMYTIME(&stop_time_val);
|
||||||
}
|
}
|
||||||
/* Function : get_time
|
/* Function : get_time
|
||||||
Return an abstract "ticks" number that signifies time on the system.
|
Return an abstract "ticks" number that signifies time on the system.
|
||||||
|
|
||||||
Actual value returned may be cpu cycles, milliseconds or any other value,
|
Actual value returned may be cpu cycles, milliseconds or any other
|
||||||
as long as it can be converted to seconds by <time_in_secs>.
|
value, as long as it can be converted to seconds by <time_in_secs>. This
|
||||||
This methodology is taken to accomodate any hardware or simulated platform.
|
methodology is taken to accomodate any hardware or simulated platform. The
|
||||||
The sample implementation returns millisecs by default,
|
sample implementation returns millisecs by default, and the resolution is
|
||||||
and the resolution is controlled by <TIMER_RES_DIVIDER>
|
controlled by <TIMER_RES_DIVIDER>
|
||||||
*/
|
*/
|
||||||
CORE_TICKS get_time(void) {
|
CORE_TICKS
|
||||||
CORE_TICKS elapsed=(CORE_TICKS)(MYTIMEDIFF(stop_time_val, start_time_val));
|
get_time(void)
|
||||||
return elapsed;
|
{
|
||||||
|
CORE_TICKS elapsed
|
||||||
|
= (CORE_TICKS)(MYTIMEDIFF(stop_time_val, start_time_val));
|
||||||
|
return elapsed;
|
||||||
}
|
}
|
||||||
/* Function : time_in_secs
|
/* Function : time_in_secs
|
||||||
Convert the value returned by get_time to seconds.
|
Convert the value returned by get_time to seconds.
|
||||||
|
|
||||||
The <secs_ret> type is used to accomodate systems with no support for floating point.
|
The <secs_ret> type is used to accomodate systems with no support for
|
||||||
Default implementation implemented by the EE_TICKS_PER_SEC macro above.
|
floating point. Default implementation implemented by the EE_TICKS_PER_SEC
|
||||||
|
macro above.
|
||||||
*/
|
*/
|
||||||
secs_ret time_in_secs(CORE_TICKS ticks) {
|
secs_ret
|
||||||
secs_ret retval=((secs_ret)ticks) / (secs_ret)EE_TICKS_PER_SEC;
|
time_in_secs(CORE_TICKS ticks)
|
||||||
return retval;
|
{
|
||||||
|
secs_ret retval = ((secs_ret)ticks) / (secs_ret)EE_TICKS_PER_SEC;
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
ee_u32 default_num_contexts=1;
|
ee_u32 default_num_contexts = 1;
|
||||||
|
|
||||||
/* Function : portable_init
|
/* Function : portable_init
|
||||||
Target specific initialization code
|
Target specific initialization code
|
||||||
Test for some common mistakes.
|
Test for some common mistakes.
|
||||||
*/
|
*/
|
||||||
void portable_init(core_portable *p, int *argc, char *argv[])
|
void
|
||||||
|
portable_init(core_portable *p, int *argc, char *argv[])
|
||||||
{
|
{
|
||||||
#error "Call board initialization routines in portable init (if needed), in particular initialize UART!\n"
|
#error \
|
||||||
if (sizeof(ee_ptr_int) != sizeof(ee_u8 *)) {
|
"Call board initialization routines in portable init (if needed), in particular initialize UART!\n"
|
||||||
ee_printf("ERROR! Please define ee_ptr_int to a type that holds a pointer!\n");
|
if (sizeof(ee_ptr_int) != sizeof(ee_u8 *))
|
||||||
}
|
{
|
||||||
if (sizeof(ee_u32) != 4) {
|
ee_printf(
|
||||||
ee_printf("ERROR! Please define ee_u32 to a 32b unsigned type!\n");
|
"ERROR! Please define ee_ptr_int to a type that holds a "
|
||||||
}
|
"pointer!\n");
|
||||||
p->portable_id=1;
|
}
|
||||||
|
if (sizeof(ee_u32) != 4)
|
||||||
|
{
|
||||||
|
ee_printf("ERROR! Please define ee_u32 to a 32b unsigned type!\n");
|
||||||
|
}
|
||||||
|
p->portable_id = 1;
|
||||||
}
|
}
|
||||||
/* Function : portable_fini
|
/* Function : portable_fini
|
||||||
Target specific final code
|
Target specific final code
|
||||||
*/
|
*/
|
||||||
void portable_fini(core_portable *p)
|
void
|
||||||
|
portable_fini(core_portable *p)
|
||||||
{
|
{
|
||||||
p->portable_id=0;
|
p->portable_id = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
179
riscv-coremark/coremark/barebones/core_portme.h
Executable file → Normal file
179
riscv-coremark/coremark/barebones/core_portme.h
Executable file → Normal file
@ -16,178 +16,189 @@ limitations under the License.
|
|||||||
Original Author: Shay Gal-on
|
Original Author: Shay Gal-on
|
||||||
*/
|
*/
|
||||||
/* Topic : Description
|
/* Topic : Description
|
||||||
This file contains configuration constants required to execute on different platforms
|
This file contains configuration constants required to execute on
|
||||||
|
different platforms
|
||||||
*/
|
*/
|
||||||
#ifndef CORE_PORTME_H
|
#ifndef CORE_PORTME_H
|
||||||
#define CORE_PORTME_H
|
#define CORE_PORTME_H
|
||||||
/************************/
|
/************************/
|
||||||
/* Data types and settings */
|
/* Data types and settings */
|
||||||
/************************/
|
/************************/
|
||||||
/* Configuration : HAS_FLOAT
|
/* Configuration : HAS_FLOAT
|
||||||
Define to 1 if the platform supports floating point.
|
Define to 1 if the platform supports floating point.
|
||||||
*/
|
*/
|
||||||
#ifndef HAS_FLOAT
|
#ifndef HAS_FLOAT
|
||||||
#define HAS_FLOAT 1
|
#define HAS_FLOAT 1
|
||||||
#endif
|
#endif
|
||||||
/* Configuration : HAS_TIME_H
|
/* Configuration : HAS_TIME_H
|
||||||
Define to 1 if platform has the time.h header file,
|
Define to 1 if platform has the time.h header file,
|
||||||
and implementation of functions thereof.
|
and implementation of functions thereof.
|
||||||
*/
|
*/
|
||||||
#ifndef HAS_TIME_H
|
#ifndef HAS_TIME_H
|
||||||
#define HAS_TIME_H 1
|
#define HAS_TIME_H 1
|
||||||
#endif
|
#endif
|
||||||
/* Configuration : USE_CLOCK
|
/* Configuration : USE_CLOCK
|
||||||
Define to 1 if platform has the time.h header file,
|
Define to 1 if platform has the time.h header file,
|
||||||
and implementation of functions thereof.
|
and implementation of functions thereof.
|
||||||
*/
|
*/
|
||||||
#ifndef USE_CLOCK
|
#ifndef USE_CLOCK
|
||||||
#define USE_CLOCK 1
|
#define USE_CLOCK 1
|
||||||
#endif
|
#endif
|
||||||
/* Configuration : HAS_STDIO
|
/* Configuration : HAS_STDIO
|
||||||
Define to 1 if the platform has stdio.h.
|
Define to 1 if the platform has stdio.h.
|
||||||
*/
|
*/
|
||||||
#ifndef HAS_STDIO
|
#ifndef HAS_STDIO
|
||||||
#define HAS_STDIO 0
|
#define HAS_STDIO 0
|
||||||
#endif
|
#endif
|
||||||
/* Configuration : HAS_PRINTF
|
/* Configuration : HAS_PRINTF
|
||||||
Define to 1 if the platform has stdio.h and implements the printf function.
|
Define to 1 if the platform has stdio.h and implements the printf
|
||||||
|
function.
|
||||||
*/
|
*/
|
||||||
#ifndef HAS_PRINTF
|
#ifndef HAS_PRINTF
|
||||||
#define HAS_PRINTF 0
|
#define HAS_PRINTF 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* Definitions : COMPILER_VERSION, COMPILER_FLAGS, MEM_LOCATION
|
/* Definitions : COMPILER_VERSION, COMPILER_FLAGS, MEM_LOCATION
|
||||||
Initialize these strings per platform
|
Initialize these strings per platform
|
||||||
*/
|
*/
|
||||||
#ifndef COMPILER_VERSION
|
#ifndef COMPILER_VERSION
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
#define COMPILER_VERSION "GCC"__VERSION__
|
#define COMPILER_VERSION "GCC"__VERSION__
|
||||||
#else
|
#else
|
||||||
#define COMPILER_VERSION "Please put compiler version here (e.g. gcc 4.1)"
|
#define COMPILER_VERSION "Please put compiler version here (e.g. gcc 4.1)"
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
#ifndef COMPILER_FLAGS
|
|
||||||
#define COMPILER_FLAGS FLAGS_STR /* "Please put compiler flags here (e.g. -o3)" */
|
|
||||||
#endif
|
#endif
|
||||||
#ifndef MEM_LOCATION
|
#ifndef COMPILER_FLAGS
|
||||||
#define MEM_LOCATION "STACK"
|
#define COMPILER_FLAGS \
|
||||||
|
FLAGS_STR /* "Please put compiler flags here (e.g. -o3)" */
|
||||||
|
#endif
|
||||||
|
#ifndef MEM_LOCATION
|
||||||
|
#define MEM_LOCATION "STACK"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Data Types :
|
/* Data Types :
|
||||||
To avoid compiler issues, define the data types that need ot be used for 8b, 16b and 32b in <core_portme.h>.
|
To avoid compiler issues, define the data types that need ot be used for
|
||||||
|
8b, 16b and 32b in <core_portme.h>.
|
||||||
*Imprtant* :
|
|
||||||
ee_ptr_int needs to be the data type used to hold pointers, otherwise coremark may fail!!!
|
*Imprtant* :
|
||||||
|
ee_ptr_int needs to be the data type used to hold pointers, otherwise
|
||||||
|
coremark may fail!!!
|
||||||
*/
|
*/
|
||||||
typedef signed short ee_s16;
|
typedef signed short ee_s16;
|
||||||
typedef unsigned short ee_u16;
|
typedef unsigned short ee_u16;
|
||||||
typedef signed int ee_s32;
|
typedef signed int ee_s32;
|
||||||
typedef double ee_f32;
|
typedef double ee_f32;
|
||||||
typedef unsigned char ee_u8;
|
typedef unsigned char ee_u8;
|
||||||
typedef unsigned int ee_u32;
|
typedef unsigned int ee_u32;
|
||||||
typedef ee_u32 ee_ptr_int;
|
typedef ee_u32 ee_ptr_int;
|
||||||
typedef size_t ee_size_t;
|
typedef size_t ee_size_t;
|
||||||
#define NULL ((void *)0)
|
#define NULL ((void *)0)
|
||||||
/* align_mem :
|
/* align_mem :
|
||||||
This macro is used to align an offset to point to a 32b value. It is used in the Matrix algorithm to initialize the input memory blocks.
|
This macro is used to align an offset to point to a 32b value. It is
|
||||||
|
used in the Matrix algorithm to initialize the input memory blocks.
|
||||||
*/
|
*/
|
||||||
#define align_mem(x) (void *)(4 + (((ee_ptr_int)(x) - 1) & ~3))
|
#define align_mem(x) (void *)(4 + (((ee_ptr_int)(x)-1) & ~3))
|
||||||
|
|
||||||
/* Configuration : CORE_TICKS
|
/* Configuration : CORE_TICKS
|
||||||
Define type of return from the timing functions.
|
Define type of return from the timing functions.
|
||||||
*/
|
*/
|
||||||
#define CORETIMETYPE ee_u32
|
#define CORETIMETYPE ee_u32
|
||||||
typedef ee_u32 CORE_TICKS;
|
typedef ee_u32 CORE_TICKS;
|
||||||
|
|
||||||
/* Configuration : SEED_METHOD
|
/* Configuration : SEED_METHOD
|
||||||
Defines method to get seed values that cannot be computed at compile time.
|
Defines method to get seed values that cannot be computed at compile
|
||||||
|
time.
|
||||||
Valid values :
|
|
||||||
SEED_ARG - from command line.
|
Valid values :
|
||||||
SEED_FUNC - from a system function.
|
SEED_ARG - from command line.
|
||||||
SEED_VOLATILE - from volatile variables.
|
SEED_FUNC - from a system function.
|
||||||
|
SEED_VOLATILE - from volatile variables.
|
||||||
*/
|
*/
|
||||||
#ifndef SEED_METHOD
|
#ifndef SEED_METHOD
|
||||||
#define SEED_METHOD SEED_VOLATILE
|
#define SEED_METHOD SEED_VOLATILE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Configuration : MEM_METHOD
|
/* Configuration : MEM_METHOD
|
||||||
Defines method to get a block of memry.
|
Defines method to get a block of memry.
|
||||||
|
|
||||||
Valid values :
|
Valid values :
|
||||||
MEM_MALLOC - for platforms that implement malloc and have malloc.h.
|
MEM_MALLOC - for platforms that implement malloc and have malloc.h.
|
||||||
MEM_STATIC - to use a static memory array.
|
MEM_STATIC - to use a static memory array.
|
||||||
MEM_STACK - to allocate the data block on the stack (NYI).
|
MEM_STACK - to allocate the data block on the stack (NYI).
|
||||||
*/
|
*/
|
||||||
#ifndef MEM_METHOD
|
#ifndef MEM_METHOD
|
||||||
#define MEM_METHOD MEM_STACK
|
#define MEM_METHOD MEM_STACK
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Configuration : MULTITHREAD
|
/* Configuration : MULTITHREAD
|
||||||
Define for parallel execution
|
Define for parallel execution
|
||||||
|
|
||||||
Valid values :
|
Valid values :
|
||||||
1 - only one context (default).
|
1 - only one context (default).
|
||||||
N>1 - will execute N copies in parallel.
|
N>1 - will execute N copies in parallel.
|
||||||
|
|
||||||
Note :
|
Note :
|
||||||
If this flag is defined to more then 1, an implementation for launching parallel contexts must be defined.
|
If this flag is defined to more then 1, an implementation for launching
|
||||||
|
parallel contexts must be defined.
|
||||||
Two sample implementations are provided. Use <USE_PTHREAD> or <USE_FORK> to enable them.
|
|
||||||
|
Two sample implementations are provided. Use <USE_PTHREAD> or <USE_FORK>
|
||||||
It is valid to have a different implementation of <core_start_parallel> and <core_end_parallel> in <core_portme.c>,
|
to enable them.
|
||||||
to fit a particular architecture.
|
|
||||||
|
It is valid to have a different implementation of <core_start_parallel>
|
||||||
|
and <core_end_parallel> in <core_portme.c>, to fit a particular architecture.
|
||||||
*/
|
*/
|
||||||
#ifndef MULTITHREAD
|
#ifndef MULTITHREAD
|
||||||
#define MULTITHREAD 1
|
#define MULTITHREAD 1
|
||||||
#define USE_PTHREAD 0
|
#define USE_PTHREAD 0
|
||||||
#define USE_FORK 0
|
#define USE_FORK 0
|
||||||
#define USE_SOCKET 0
|
#define USE_SOCKET 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Configuration : MAIN_HAS_NOARGC
|
/* Configuration : MAIN_HAS_NOARGC
|
||||||
Needed if platform does not support getting arguments to main.
|
Needed if platform does not support getting arguments to main.
|
||||||
|
|
||||||
Valid values :
|
Valid values :
|
||||||
0 - argc/argv to main is supported
|
0 - argc/argv to main is supported
|
||||||
1 - argc/argv to main is not supported
|
1 - argc/argv to main is not supported
|
||||||
|
|
||||||
Note :
|
Note :
|
||||||
This flag only matters if MULTITHREAD has been defined to a value greater then 1.
|
This flag only matters if MULTITHREAD has been defined to a value
|
||||||
|
greater then 1.
|
||||||
*/
|
*/
|
||||||
#ifndef MAIN_HAS_NOARGC
|
#ifndef MAIN_HAS_NOARGC
|
||||||
#define MAIN_HAS_NOARGC 0
|
#define MAIN_HAS_NOARGC 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Configuration : MAIN_HAS_NORETURN
|
/* Configuration : MAIN_HAS_NORETURN
|
||||||
Needed if platform does not support returning a value from main.
|
Needed if platform does not support returning a value from main.
|
||||||
|
|
||||||
Valid values :
|
Valid values :
|
||||||
0 - main returns an int, and return value will be 0.
|
0 - main returns an int, and return value will be 0.
|
||||||
1 - platform does not support returning a value from main
|
1 - platform does not support returning a value from main
|
||||||
*/
|
*/
|
||||||
#ifndef MAIN_HAS_NORETURN
|
#ifndef MAIN_HAS_NORETURN
|
||||||
#define MAIN_HAS_NORETURN 0
|
#define MAIN_HAS_NORETURN 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Variable : default_num_contexts
|
/* Variable : default_num_contexts
|
||||||
Not used for this simple port, must cintain the value 1.
|
Not used for this simple port, must cintain the value 1.
|
||||||
*/
|
*/
|
||||||
extern ee_u32 default_num_contexts;
|
extern ee_u32 default_num_contexts;
|
||||||
|
|
||||||
typedef struct CORE_PORTABLE_S {
|
typedef struct CORE_PORTABLE_S
|
||||||
ee_u8 portable_id;
|
{
|
||||||
|
ee_u8 portable_id;
|
||||||
} core_portable;
|
} core_portable;
|
||||||
|
|
||||||
/* target specific init/fini */
|
/* target specific init/fini */
|
||||||
void portable_init(core_portable *p, int *argc, char *argv[]);
|
void portable_init(core_portable *p, int *argc, char *argv[]);
|
||||||
void portable_fini(core_portable *p);
|
void portable_fini(core_portable *p);
|
||||||
|
|
||||||
#if !defined(PROFILE_RUN) && !defined(PERFORMANCE_RUN) && !defined(VALIDATION_RUN)
|
#if !defined(PROFILE_RUN) && !defined(PERFORMANCE_RUN) \
|
||||||
#if (TOTAL_DATA_SIZE==1200)
|
&& !defined(VALIDATION_RUN)
|
||||||
|
#if (TOTAL_DATA_SIZE == 1200)
|
||||||
#define PROFILE_RUN 1
|
#define PROFILE_RUN 1
|
||||||
#elif (TOTAL_DATA_SIZE==2000)
|
#elif (TOTAL_DATA_SIZE == 2000)
|
||||||
#define PERFORMANCE_RUN 1
|
#define PERFORMANCE_RUN 1
|
||||||
#else
|
#else
|
||||||
#define VALIDATION_RUN 1
|
#define VALIDATION_RUN 1
|
||||||
|
164
riscv-coremark/coremark/barebones/cvt.c
Executable file → Normal file
164
riscv-coremark/coremark/barebones/cvt.c
Executable file → Normal file
@ -17,101 +17,111 @@ limitations under the License.
|
|||||||
#define CVTBUFSIZE 80
|
#define CVTBUFSIZE 80
|
||||||
static char CVTBUF[CVTBUFSIZE];
|
static char CVTBUF[CVTBUFSIZE];
|
||||||
|
|
||||||
static char *cvt(double arg, int ndigits, int *decpt, int *sign, char *buf, int eflag)
|
static char *
|
||||||
|
cvt(double arg, int ndigits, int *decpt, int *sign, char *buf, int eflag)
|
||||||
{
|
{
|
||||||
int r2;
|
int r2;
|
||||||
double fi, fj;
|
double fi, fj;
|
||||||
char *p, *p1;
|
char * p, *p1;
|
||||||
|
|
||||||
if (ndigits < 0) ndigits = 0;
|
if (ndigits < 0)
|
||||||
if (ndigits >= CVTBUFSIZE - 1) ndigits = CVTBUFSIZE - 2;
|
ndigits = 0;
|
||||||
r2 = 0;
|
if (ndigits >= CVTBUFSIZE - 1)
|
||||||
*sign = 0;
|
ndigits = CVTBUFSIZE - 2;
|
||||||
p = &buf[0];
|
r2 = 0;
|
||||||
if (arg < 0)
|
*sign = 0;
|
||||||
{
|
p = &buf[0];
|
||||||
*sign = 1;
|
if (arg < 0)
|
||||||
arg = -arg;
|
{
|
||||||
}
|
*sign = 1;
|
||||||
arg = modf(arg, &fi);
|
arg = -arg;
|
||||||
p1 = &buf[CVTBUFSIZE];
|
}
|
||||||
|
arg = modf(arg, &fi);
|
||||||
|
p1 = &buf[CVTBUFSIZE];
|
||||||
|
|
||||||
if (fi != 0)
|
if (fi != 0)
|
||||||
{
|
|
||||||
p1 = &buf[CVTBUFSIZE];
|
|
||||||
while (fi != 0)
|
|
||||||
{
|
{
|
||||||
fj = modf(fi / 10, &fi);
|
p1 = &buf[CVTBUFSIZE];
|
||||||
*--p1 = (int)((fj + .03) * 10) + '0';
|
while (fi != 0)
|
||||||
r2++;
|
{
|
||||||
|
fj = modf(fi / 10, &fi);
|
||||||
|
*--p1 = (int)((fj + .03) * 10) + '0';
|
||||||
|
r2++;
|
||||||
|
}
|
||||||
|
while (p1 < &buf[CVTBUFSIZE])
|
||||||
|
*p++ = *p1++;
|
||||||
}
|
}
|
||||||
while (p1 < &buf[CVTBUFSIZE]) *p++ = *p1++;
|
else if (arg > 0)
|
||||||
}
|
|
||||||
else if (arg > 0)
|
|
||||||
{
|
|
||||||
while ((fj = arg * 10) < 1)
|
|
||||||
{
|
{
|
||||||
arg = fj;
|
while ((fj = arg * 10) < 1)
|
||||||
r2--;
|
{
|
||||||
|
arg = fj;
|
||||||
|
r2--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
p1 = &buf[ndigits];
|
||||||
p1 = &buf[ndigits];
|
if (eflag == 0)
|
||||||
if (eflag == 0) p1 += r2;
|
p1 += r2;
|
||||||
*decpt = r2;
|
*decpt = r2;
|
||||||
if (p1 < &buf[0])
|
if (p1 < &buf[0])
|
||||||
{
|
{
|
||||||
buf[0] = '\0';
|
buf[0] = '\0';
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
while (p <= p1 && p < &buf[CVTBUFSIZE])
|
||||||
|
{
|
||||||
|
arg *= 10;
|
||||||
|
arg = modf(arg, &fj);
|
||||||
|
*p++ = (int)fj + '0';
|
||||||
|
}
|
||||||
|
if (p1 >= &buf[CVTBUFSIZE])
|
||||||
|
{
|
||||||
|
buf[CVTBUFSIZE - 1] = '\0';
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
p = p1;
|
||||||
|
*p1 += 5;
|
||||||
|
while (*p1 > '9')
|
||||||
|
{
|
||||||
|
*p1 = '0';
|
||||||
|
if (p1 > buf)
|
||||||
|
++*--p1;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*p1 = '1';
|
||||||
|
(*decpt)++;
|
||||||
|
if (eflag == 0)
|
||||||
|
{
|
||||||
|
if (p > buf)
|
||||||
|
*p = '0';
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*p = '\0';
|
||||||
return buf;
|
return buf;
|
||||||
}
|
|
||||||
while (p <= p1 && p < &buf[CVTBUFSIZE])
|
|
||||||
{
|
|
||||||
arg *= 10;
|
|
||||||
arg = modf(arg, &fj);
|
|
||||||
*p++ = (int) fj + '0';
|
|
||||||
}
|
|
||||||
if (p1 >= &buf[CVTBUFSIZE])
|
|
||||||
{
|
|
||||||
buf[CVTBUFSIZE - 1] = '\0';
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
p = p1;
|
|
||||||
*p1 += 5;
|
|
||||||
while (*p1 > '9')
|
|
||||||
{
|
|
||||||
*p1 = '0';
|
|
||||||
if (p1 > buf)
|
|
||||||
++*--p1;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
*p1 = '1';
|
|
||||||
(*decpt)++;
|
|
||||||
if (eflag == 0)
|
|
||||||
{
|
|
||||||
if (p > buf) *p = '0';
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*p = '\0';
|
|
||||||
return buf;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char *ecvt(double arg, int ndigits, int *decpt, int *sign)
|
char *
|
||||||
|
ecvt(double arg, int ndigits, int *decpt, int *sign)
|
||||||
{
|
{
|
||||||
return cvt(arg, ndigits, decpt, sign, CVTBUF, 1);
|
return cvt(arg, ndigits, decpt, sign, CVTBUF, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *ecvtbuf(double arg, int ndigits, int *decpt, int *sign, char *buf)
|
char *
|
||||||
|
ecvtbuf(double arg, int ndigits, int *decpt, int *sign, char *buf)
|
||||||
{
|
{
|
||||||
return cvt(arg, ndigits, decpt, sign, buf, 1);
|
return cvt(arg, ndigits, decpt, sign, buf, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *fcvt(double arg, int ndigits, int *decpt, int *sign)
|
char *
|
||||||
|
fcvt(double arg, int ndigits, int *decpt, int *sign)
|
||||||
{
|
{
|
||||||
return cvt(arg, ndigits, decpt, sign, CVTBUF, 0);
|
return cvt(arg, ndigits, decpt, sign, CVTBUF, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *fcvtbuf(double arg, int ndigits, int *decpt, int *sign, char *buf)
|
char *
|
||||||
|
fcvtbuf(double arg, int ndigits, int *decpt, int *sign, char *buf)
|
||||||
{
|
{
|
||||||
return cvt(arg, ndigits, decpt, sign, buf, 0);
|
return cvt(arg, ndigits, decpt, sign, buf, 0);
|
||||||
}
|
}
|
||||||
|
1067
riscv-coremark/coremark/barebones/ee_printf.c
Executable file → Normal file
1067
riscv-coremark/coremark/barebones/ee_printf.c
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -17,383 +17,431 @@ Original Author: Shay Gal-on
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* File: core_main.c
|
/* File: core_main.c
|
||||||
This file contains the framework to acquire a block of memory, seed initial parameters, tun t he benchmark and report the results.
|
This file contains the framework to acquire a block of memory, seed
|
||||||
|
initial parameters, tun t he benchmark and report the results.
|
||||||
*/
|
*/
|
||||||
#include "coremark.h"
|
#include "coremark.h"
|
||||||
|
|
||||||
/* Function: iterate
|
/* Function: iterate
|
||||||
Run the benchmark for a specified number of iterations.
|
Run the benchmark for a specified number of iterations.
|
||||||
|
|
||||||
Operation:
|
Operation:
|
||||||
For each type of benchmarked algorithm:
|
For each type of benchmarked algorithm:
|
||||||
a - Initialize the data block for the algorithm.
|
a - Initialize the data block for the algorithm.
|
||||||
b - Execute the algorithm N times.
|
b - Execute the algorithm N times.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
NULL.
|
NULL.
|
||||||
*/
|
*/
|
||||||
static ee_u16 list_known_crc[] = {(ee_u16)0xd4b0,(ee_u16)0x3340,(ee_u16)0x6a79,(ee_u16)0xe714,(ee_u16)0xe3c1};
|
static ee_u16 list_known_crc[] = { (ee_u16)0xd4b0,
|
||||||
static ee_u16 matrix_known_crc[] = {(ee_u16)0xbe52,(ee_u16)0x1199,(ee_u16)0x5608,(ee_u16)0x1fd7,(ee_u16)0x0747};
|
(ee_u16)0x3340,
|
||||||
static ee_u16 state_known_crc[] = {(ee_u16)0x5e47,(ee_u16)0x39bf,(ee_u16)0xe5a4,(ee_u16)0x8e3a,(ee_u16)0x8d84};
|
(ee_u16)0x6a79,
|
||||||
int gg_printf(const char *fmt, ...);
|
(ee_u16)0xe714,
|
||||||
int sendstring(const char *p);
|
(ee_u16)0xe3c1 };
|
||||||
void _send_char(char c);
|
static ee_u16 matrix_known_crc[] = { (ee_u16)0xbe52,
|
||||||
void *iterate(void *pres) {
|
(ee_u16)0x1199,
|
||||||
ee_u32 i;
|
(ee_u16)0x5608,
|
||||||
ee_u16 crc;
|
(ee_u16)0x1fd7,
|
||||||
core_results *res=(core_results *)pres;
|
(ee_u16)0x0747 };
|
||||||
ee_u32 iterations=res->iterations;
|
static ee_u16 state_known_crc[] = { (ee_u16)0x5e47,
|
||||||
res->crc=0;
|
(ee_u16)0x39bf,
|
||||||
res->crclist=0;
|
(ee_u16)0xe5a4,
|
||||||
res->crcmatrix=0;
|
(ee_u16)0x8e3a,
|
||||||
res->crcstate=0;
|
(ee_u16)0x8d84 };
|
||||||
|
void *
|
||||||
|
iterate(void *pres)
|
||||||
|
{
|
||||||
|
ee_u32 i;
|
||||||
|
ee_u16 crc;
|
||||||
|
core_results *res = (core_results *)pres;
|
||||||
|
ee_u32 iterations = res->iterations;
|
||||||
|
res->crc = 0;
|
||||||
|
res->crclist = 0;
|
||||||
|
res->crcmatrix = 0;
|
||||||
|
res->crcstate = 0;
|
||||||
|
|
||||||
for (i=0; i<iterations; i++) {
|
for (i = 0; i < iterations; i++)
|
||||||
crc=core_bench_list(res,1);
|
{
|
||||||
res->crc=crcu16(crc,res->crc);
|
crc = core_bench_list(res, 1);
|
||||||
crc=core_bench_list(res,-1);
|
res->crc = crcu16(crc, res->crc);
|
||||||
res->crc=crcu16(crc,res->crc);
|
crc = core_bench_list(res, -1);
|
||||||
if (i==0) res->crclist=res->crc;
|
res->crc = crcu16(crc, res->crc);
|
||||||
}
|
if (i == 0)
|
||||||
return NULL;
|
res->crclist = res->crc;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (SEED_METHOD==SEED_ARG)
|
#if (SEED_METHOD == SEED_ARG)
|
||||||
ee_s32 get_seed_args(int i, int argc, char *argv[]);
|
ee_s32 get_seed_args(int i, int argc, char *argv[]);
|
||||||
#define get_seed(x) (ee_s16)get_seed_args(x,argc,argv)
|
#define get_seed(x) (ee_s16) get_seed_args(x, argc, argv)
|
||||||
#define get_seed_32(x) get_seed_args(x,argc,argv)
|
#define get_seed_32(x) get_seed_args(x, argc, argv)
|
||||||
#else /* via function or volatile */
|
#else /* via function or volatile */
|
||||||
ee_s32 get_seed_32(int i);
|
ee_s32 get_seed_32(int i);
|
||||||
#define get_seed(x) (ee_s16)get_seed_32(x)
|
#define get_seed(x) (ee_s16) get_seed_32(x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (MEM_METHOD==MEM_STATIC)
|
#if (MEM_METHOD == MEM_STATIC)
|
||||||
ee_u8 static_memblk[TOTAL_DATA_SIZE];
|
ee_u8 static_memblk[TOTAL_DATA_SIZE];
|
||||||
#endif
|
#endif
|
||||||
char *mem_name[3] = {"Static","Heap","Stack"};
|
char *mem_name[3] = { "Static", "Heap", "Stack" };
|
||||||
/* Function: main
|
/* Function: main
|
||||||
Main entry routine for the benchmark.
|
Main entry routine for the benchmark.
|
||||||
This function is responsible for the following steps:
|
This function is responsible for the following steps:
|
||||||
|
|
||||||
1 - Initialize input seeds from a source that cannot be determined at compile time.
|
1 - Initialize input seeds from a source that cannot be determined at
|
||||||
2 - Initialize memory block for use.
|
compile time. 2 - Initialize memory block for use. 3 - Run and time the
|
||||||
3 - Run and time the benchmark.
|
benchmark. 4 - Report results, testing the validity of the output if the
|
||||||
4 - Report results, testing the validity of the output if the seeds are known.
|
seeds are known.
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
1 - first seed : Any value
|
1 - first seed : Any value
|
||||||
2 - second seed : Must be identical to first for iterations to be identical
|
2 - second seed : Must be identical to first for iterations to be
|
||||||
3 - third seed : Any value, should be at least an order of magnitude less then the input size, but bigger then 32.
|
identical 3 - third seed : Any value, should be at least an order of
|
||||||
4 - Iterations : Special, if set to 0, iterations will be automatically determined such that the benchmark will run between 10 to 100 secs
|
magnitude less then the input size, but bigger then 32. 4 - Iterations :
|
||||||
|
Special, if set to 0, iterations will be automatically determined such that
|
||||||
|
the benchmark will run between 10 to 100 secs
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if MAIN_HAS_NOARGC
|
#if MAIN_HAS_NOARGC
|
||||||
MAIN_RETURN_TYPE main(void) {
|
MAIN_RETURN_TYPE
|
||||||
int argc=0;
|
main(void)
|
||||||
char *argv[1];
|
{
|
||||||
|
int argc = 0;
|
||||||
|
char *argv[1];
|
||||||
#else
|
#else
|
||||||
MAIN_RETURN_TYPE main(int argc, char *argv[]) {
|
MAIN_RETURN_TYPE
|
||||||
|
main(int argc, char *argv[])
|
||||||
|
{
|
||||||
#endif
|
#endif
|
||||||
//const char s[] = "Elizabeth";
|
ee_printf("SHOWTIME\n");
|
||||||
ee_printf("eeprint");
|
ee_u16 i, j = 0, num_algorithms = 0;
|
||||||
//ee_printf("Trying to print: %d", 0);
|
ee_s16 known_id = -1, total_errors = 0;
|
||||||
/*gg_printf("Elizabeth");*/
|
ee_u16 seedcrc = 0;
|
||||||
//sendstring("Elizabeth");
|
CORE_TICKS total_time;
|
||||||
|
core_results results[MULTITHREAD];
|
||||||
//sendstring(s);
|
#if (MEM_METHOD == MEM_STACK)
|
||||||
//return(0);
|
ee_u8 stack_memblock[TOTAL_DATA_SIZE * MULTITHREAD];
|
||||||
ee_u16 i,j=0,num_algorithms=0;
|
|
||||||
ee_s16 known_id=-1,total_errors=0;
|
|
||||||
ee_u16 seedcrc=0;
|
|
||||||
CORE_TICKS total_time;
|
|
||||||
core_results results[MULTITHREAD];
|
|
||||||
#if (MEM_METHOD==MEM_STACK)
|
|
||||||
ee_u8 stack_memblock[TOTAL_DATA_SIZE*MULTITHREAD];
|
|
||||||
#endif
|
#endif
|
||||||
/* first call any initializations needed */
|
/* first call any initializations needed */
|
||||||
portable_init(&(results[0].port), &argc, argv);
|
portable_init(&(results[0].port), &argc, argv);
|
||||||
/* First some checks to make sure benchmark will run ok */
|
/* First some checks to make sure benchmark will run ok */
|
||||||
if (sizeof(struct list_head_s)>128) {
|
if (sizeof(struct list_head_s) > 128)
|
||||||
ee_printf("list_head structure too big for comparable data!\n");
|
{
|
||||||
return MAIN_RETURN_VAL;
|
ee_printf("list_head structure too big for comparable data!\n");
|
||||||
}
|
return MAIN_RETURN_VAL;
|
||||||
results[0].seed1=get_seed(1);
|
}
|
||||||
results[0].seed2=get_seed(2);
|
results[0].seed1 = get_seed(1);
|
||||||
results[0].seed3=get_seed(3);
|
results[0].seed2 = get_seed(2);
|
||||||
results[0].iterations=get_seed_32(4);
|
results[0].seed3 = get_seed(3);
|
||||||
|
results[0].iterations = get_seed_32(4);
|
||||||
#if CORE_DEBUG
|
#if CORE_DEBUG
|
||||||
results[0].iterations=1;
|
results[0].iterations = 1;
|
||||||
#endif
|
#endif
|
||||||
results[0].execs=get_seed_32(5);
|
results[0].execs = get_seed_32(5);
|
||||||
if (results[0].execs==0) { /* if not supplied, execute all algorithms */
|
if (results[0].execs == 0)
|
||||||
results[0].execs=ALL_ALGORITHMS_MASK;
|
{ /* if not supplied, execute all algorithms */
|
||||||
}
|
results[0].execs = ALL_ALGORITHMS_MASK;
|
||||||
/* put in some default values based on one seed only for easy testing */
|
}
|
||||||
if ((results[0].seed1==0) && (results[0].seed2==0) && (results[0].seed3==0)) { /* validation run */
|
/* put in some default values based on one seed only for easy testing */
|
||||||
results[0].seed1=0;
|
if ((results[0].seed1 == 0) && (results[0].seed2 == 0)
|
||||||
results[0].seed2=0;
|
&& (results[0].seed3 == 0))
|
||||||
results[0].seed3=0x66;
|
{ /* perfromance run */
|
||||||
}
|
results[0].seed1 = 0;
|
||||||
if ((results[0].seed1==1) && (results[0].seed2==0) && (results[0].seed3==0)) { /* perfromance run */
|
results[0].seed2 = 0;
|
||||||
results[0].seed1=0x3415;
|
results[0].seed3 = 0x66;
|
||||||
results[0].seed2=0x3415;
|
}
|
||||||
results[0].seed3=0x66;
|
if ((results[0].seed1 == 1) && (results[0].seed2 == 0)
|
||||||
}
|
&& (results[0].seed3 == 0))
|
||||||
#if (MEM_METHOD==MEM_STATIC)
|
{ /* validation run */
|
||||||
results[0].memblock[0]=(void *)static_memblk;
|
results[0].seed1 = 0x3415;
|
||||||
results[0].size=TOTAL_DATA_SIZE;
|
results[0].seed2 = 0x3415;
|
||||||
ee_printf("%d \n total data size", TOTAL_DATA_SIZE);
|
results[0].seed3 = 0x66;
|
||||||
results[0].err=0;
|
}
|
||||||
#if (MULTITHREAD>1)
|
#if (MEM_METHOD == MEM_STATIC)
|
||||||
#error "Cannot use a static data area with multiple contexts!"
|
results[0].memblock[0] = (void *)static_memblk;
|
||||||
#endif
|
results[0].size = TOTAL_DATA_SIZE;
|
||||||
#elif (MEM_METHOD==MEM_MALLOC)
|
results[0].err = 0;
|
||||||
for (i=0 ; i<MULTITHREAD; i++) {
|
#if (MULTITHREAD > 1)
|
||||||
ee_s32 malloc_override=get_seed(7);
|
#error "Cannot use a static data area with multiple contexts!"
|
||||||
if (malloc_override != 0)
|
#endif
|
||||||
results[i].size=malloc_override;
|
#elif (MEM_METHOD == MEM_MALLOC)
|
||||||
ee_printf("%d \n malloc datasize", malloc_override);
|
for (i = 0; i < MULTITHREAD; i++)
|
||||||
else
|
{
|
||||||
results[i].size=TOTAL_DATA_SIZE;
|
ee_s32 malloc_override = get_seed(7);
|
||||||
results[i].memblock[0]=portable_malloc(results[i].size);
|
if (malloc_override != 0)
|
||||||
results[i].seed1=results[0].seed1;
|
results[i].size = malloc_override;
|
||||||
results[i].seed2=results[0].seed2;
|
else
|
||||||
results[i].seed3=results[0].seed3;
|
results[i].size = TOTAL_DATA_SIZE;
|
||||||
results[i].err=0;
|
results[i].memblock[0] = portable_malloc(results[i].size);
|
||||||
results[i].execs=results[0].execs;
|
results[i].seed1 = results[0].seed1;
|
||||||
}
|
results[i].seed2 = results[0].seed2;
|
||||||
#elif (MEM_METHOD==MEM_STACK)
|
results[i].seed3 = results[0].seed3;
|
||||||
for (i=0 ; i<MULTITHREAD; i++) {
|
results[i].err = 0;
|
||||||
results[i].memblock[0]=stack_memblock+i*TOTAL_DATA_SIZE;
|
results[i].execs = results[0].execs;
|
||||||
results[i].size=TOTAL_DATA_SIZE;
|
}
|
||||||
results[i].seed1=results[0].seed1;
|
#elif (MEM_METHOD == MEM_STACK)
|
||||||
results[i].seed2=results[0].seed2;
|
for (i = 0; i < MULTITHREAD; i++)
|
||||||
results[i].seed3=results[0].seed3;
|
{
|
||||||
results[i].err=0;
|
results[i].memblock[0] = stack_memblock + i * TOTAL_DATA_SIZE;
|
||||||
results[i].execs=results[0].execs;
|
results[i].size = TOTAL_DATA_SIZE;
|
||||||
}
|
results[i].seed1 = results[0].seed1;
|
||||||
|
results[i].seed2 = results[0].seed2;
|
||||||
|
results[i].seed3 = results[0].seed3;
|
||||||
|
results[i].err = 0;
|
||||||
|
results[i].execs = results[0].execs;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
#error "Please define a way to initialize a memory block."
|
#error "Please define a way to initialize a memory block."
|
||||||
#endif
|
#endif
|
||||||
/* Data init */
|
/* Data init */
|
||||||
/* Find out how space much we have based on number of algorithms */
|
/* Find out how space much we have based on number of algorithms */
|
||||||
for (i=0; i<NUM_ALGORITHMS; i++) {
|
for (i = 0; i < NUM_ALGORITHMS; i++)
|
||||||
if ((1<<(ee_u32)i) & results[0].execs)
|
{
|
||||||
num_algorithms++;
|
if ((1 << (ee_u32)i) & results[0].execs)
|
||||||
}
|
num_algorithms++;
|
||||||
for (i=0 ; i<MULTITHREAD; i++)
|
}
|
||||||
results[i].size=results[i].size/num_algorithms;
|
for (i = 0; i < MULTITHREAD; i++)
|
||||||
/* Assign pointers */
|
results[i].size = results[i].size / num_algorithms;
|
||||||
for (i=0; i<NUM_ALGORITHMS; i++) {
|
/* Assign pointers */
|
||||||
ee_u32 ctx;
|
for (i = 0; i < NUM_ALGORITHMS; i++)
|
||||||
if ((1<<(ee_u32)i) & results[0].execs) {
|
{
|
||||||
for (ctx=0 ; ctx<MULTITHREAD; ctx++)
|
ee_u32 ctx;
|
||||||
results[ctx].memblock[i+1]=(char *)(results[ctx].memblock[0])+results[0].size*j;
|
if ((1 << (ee_u32)i) & results[0].execs)
|
||||||
j++;
|
{
|
||||||
}
|
for (ctx = 0; ctx < MULTITHREAD; ctx++)
|
||||||
}
|
results[ctx].memblock[i + 1]
|
||||||
/* call inits */
|
= (char *)(results[ctx].memblock[0]) + results[0].size * j;
|
||||||
for (i=0 ; i<MULTITHREAD; i++) {
|
j++;
|
||||||
if (results[i].execs & ID_LIST) {
|
}
|
||||||
ee_printf("loop");
|
}
|
||||||
ee_printf("%d \n", MULTITHREAD);
|
/* call inits */
|
||||||
ee_printf("%d \n sizethread \n", results[0].size);
|
for (i = 0; i < MULTITHREAD; i++)
|
||||||
|
{
|
||||||
|
if (results[i].execs & ID_LIST)
|
||||||
|
{
|
||||||
|
results[i].list = core_list_init(
|
||||||
|
results[0].size, results[i].memblock[1], results[i].seed1);
|
||||||
|
}
|
||||||
|
if (results[i].execs & ID_MATRIX)
|
||||||
|
{
|
||||||
|
core_init_matrix(results[0].size,
|
||||||
|
results[i].memblock[2],
|
||||||
|
(ee_s32)results[i].seed1
|
||||||
|
| (((ee_s32)results[i].seed2) << 16),
|
||||||
|
&(results[i].mat));
|
||||||
|
}
|
||||||
|
if (results[i].execs & ID_STATE)
|
||||||
|
{
|
||||||
|
core_init_state(
|
||||||
|
results[0].size, results[i].seed1, results[i].memblock[3]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* automatically determine number of iterations if not set */
|
||||||
results[i].list=core_list_init(results[0].size,results[i].memblock[1],results[i].seed1);
|
if (results[0].iterations == 0)
|
||||||
|
{
|
||||||
}
|
secs_ret secs_passed = 0;
|
||||||
if (results[i].execs & ID_MATRIX) {
|
ee_u32 divisor;
|
||||||
core_init_matrix(results[0].size, results[i].memblock[2], (ee_s32)results[i].seed1 | (((ee_s32)results[i].seed2) << 16), &(results[i].mat) );
|
results[0].iterations = 1;
|
||||||
}
|
while (secs_passed < (secs_ret)1)
|
||||||
if (results[i].execs & ID_STATE) {
|
{
|
||||||
core_init_state(results[0].size,results[i].seed1,results[i].memblock[3]);
|
results[0].iterations *= 10;
|
||||||
}
|
start_time();
|
||||||
}
|
iterate(&results[0]);
|
||||||
|
stop_time();
|
||||||
/* automatically determine number of iterations if not set */
|
secs_passed = time_in_secs(get_time());
|
||||||
if (results[0].iterations==0) {
|
}
|
||||||
secs_ret secs_passed=0;
|
/* now we know it executes for at least 1 sec, set actual run time at
|
||||||
ee_u32 divisor;
|
* about 10 secs */
|
||||||
results[0].iterations=1;
|
divisor = (ee_u32)secs_passed;
|
||||||
int iterationInc = 0;
|
if (divisor == 0) /* some machines cast float to int as 0 since this
|
||||||
ee_printf("\n\nENTERING ITERATION WHILE LOOP\n");
|
conversion is not defined by ANSI, but we know at
|
||||||
while (secs_passed < (secs_ret)1) {
|
least one second passed */
|
||||||
if(iterationInc != 0)
|
divisor = 1;
|
||||||
{
|
results[0].iterations *= 1 + 10 / divisor;
|
||||||
results[0].iterations++;
|
}
|
||||||
}
|
/* perform actual benchmark */
|
||||||
ee_printf("iterations is %d\n", results[0].iterations);
|
start_time();
|
||||||
start_time();
|
#if (MULTITHREAD > 1)
|
||||||
iterate(&results[0]);
|
if (default_num_contexts > MULTITHREAD)
|
||||||
stop_time();
|
{
|
||||||
secs_passed = time_in_secs(get_time());
|
default_num_contexts = MULTITHREAD;
|
||||||
int secs_passed_int = (int)secs_passed;
|
}
|
||||||
ee_printf("secs passed is %d\n", secs_passed_int);
|
for (i = 0; i < default_num_contexts; i++)
|
||||||
iterationInc++;
|
{
|
||||||
}
|
results[i].iterations = results[0].iterations;
|
||||||
ee_printf("LEAVING ITERATION WHILE LOOP!\n\n");
|
results[i].execs = results[0].execs;
|
||||||
/* now we know it executes for at least 1 sec, set actual run time at about 10 secs */
|
core_start_parallel(&results[i]);
|
||||||
divisor=(ee_u32)secs_passed;
|
}
|
||||||
ee_printf("divisor is %lu\n", divisor);
|
for (i = 0; i < default_num_contexts; i++)
|
||||||
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 */
|
{
|
||||||
divisor=1;
|
core_stop_parallel(&results[i]);
|
||||||
results[0].iterations*=1+10/divisor;
|
}
|
||||||
ee_printf("iterations is %d\n", results[0].iterations);
|
|
||||||
}
|
|
||||||
/* perform actual benchmark */
|
|
||||||
ee_printf("iterations is %d\n", results[0].iterations);
|
|
||||||
ee_printf("Starting benchmark\n");
|
|
||||||
start_time();
|
|
||||||
#if (MULTITHREAD>1)
|
|
||||||
if (default_num_contexts>MULTITHREAD) {
|
|
||||||
default_num_contexts=MULTITHREAD;
|
|
||||||
}
|
|
||||||
for (i=0 ; i<default_num_contexts; i++) {
|
|
||||||
results[i].iterations=results[0].iterations;
|
|
||||||
results[i].execs=results[0].execs;
|
|
||||||
core_start_parallel(&results[i]);
|
|
||||||
}
|
|
||||||
for (i=0 ; i<default_num_contexts; i++) {
|
|
||||||
core_stop_parallel(&results[i]);
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
iterate(&results[0]);
|
iterate(&results[0]);
|
||||||
#endif
|
#endif
|
||||||
stop_time();
|
stop_time();
|
||||||
total_time=get_time();
|
total_time = get_time();
|
||||||
ee_printf("total time is %u\n", total_time);
|
/* get a function of the input to report */
|
||||||
ee_printf("ending benchmark\n");
|
seedcrc = crc16(results[0].seed1, seedcrc);
|
||||||
/* get a function of the input to report */
|
seedcrc = crc16(results[0].seed2, seedcrc);
|
||||||
seedcrc=crc16(results[0].seed1,seedcrc);
|
seedcrc = crc16(results[0].seed3, seedcrc);
|
||||||
seedcrc=crc16(results[0].seed2,seedcrc);
|
seedcrc = crc16(results[0].size, seedcrc);
|
||||||
seedcrc=crc16(results[0].seed3,seedcrc);
|
|
||||||
seedcrc=crc16(results[0].size,seedcrc);
|
|
||||||
|
|
||||||
switch (seedcrc) { /* test known output for common seeds */
|
|
||||||
case 0x8a02: /* seed1=0, seed2=0, seed3=0x66, size 2000 per algorithm */
|
|
||||||
known_id=0;
|
|
||||||
ee_printf("6k performance run parameters for coremark.\n");
|
|
||||||
break;
|
|
||||||
case 0x7b05: /* seed1=0x3415, seed2=0x3415, seed3=0x66, size 2000 per algorithm */
|
|
||||||
known_id=1;
|
|
||||||
ee_printf("6k validation run parameters for coremark.\n");
|
|
||||||
break;
|
|
||||||
case 0x4eaf: /* seed1=0x8, seed2=0x8, seed3=0x8, size 400 per algorithm */
|
|
||||||
known_id=2;
|
|
||||||
ee_printf("Profile generation run parameters for coremark.\n");
|
|
||||||
break;
|
|
||||||
case 0xe9f5: /* seed1=0, seed2=0, seed3=0x66, size 666 per algorithm */
|
|
||||||
known_id=3;
|
|
||||||
ee_printf("2K performance run parameters for coremark.\n");
|
|
||||||
break;
|
|
||||||
case 0x18f2: /* seed1=0x3415, seed2=0x3415, seed3=0x66, size 666 per algorithm */
|
|
||||||
known_id=4;
|
|
||||||
ee_printf("2K validation run parameters for coremark.\n");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
total_errors=-1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (known_id>=0) {
|
|
||||||
for (i=0 ; i<default_num_contexts; i++) {
|
|
||||||
results[i].err=0;
|
|
||||||
if ((results[i].execs & ID_LIST) &&
|
|
||||||
(results[i].crclist!=list_known_crc[known_id])) {
|
|
||||||
ee_printf("[%u]ERROR! list crc 0x%04x - should be 0x%04x\n",i,results[i].crclist,list_known_crc[known_id]);
|
|
||||||
results[i].err++;
|
|
||||||
}
|
|
||||||
if ((results[i].execs & ID_MATRIX) &&
|
|
||||||
(results[i].crcmatrix!=matrix_known_crc[known_id])) {
|
|
||||||
ee_printf("[%u]ERROR! matrix crc 0x%04x - should be 0x%04x\n",i,results[i].crcmatrix,matrix_known_crc[known_id]);
|
|
||||||
results[i].err++;
|
|
||||||
}
|
|
||||||
if ((results[i].execs & ID_STATE) &&
|
|
||||||
(results[i].crcstate!=state_known_crc[known_id])) {
|
|
||||||
ee_printf("[%u]ERROR! state crc 0x%04x - should be 0x%04x\n",i,results[i].crcstate,state_known_crc[known_id]);
|
|
||||||
results[i].err++;
|
|
||||||
}
|
|
||||||
total_errors+=results[i].err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
total_errors+=check_data_types();
|
|
||||||
/* and report results */
|
|
||||||
//ee_printf("CoreMark Size : %lu\n", (long unsigned) results[0].size);
|
|
||||||
ee_printf("CoreMark Size : %lu\n", (long unsigned) results[0].size);
|
|
||||||
ee_printf("Total ticks : %lu\n", (long unsigned) total_time);
|
|
||||||
#if HAS_FLOAT
|
|
||||||
ee_printf("Total time (secs): %f\n",time_in_secs(total_time));
|
|
||||||
if (time_in_secs(total_time) > 0)
|
|
||||||
ee_printf("Iterations/Sec : %f\n",default_num_contexts*results[0].iterations/time_in_secs(total_time));
|
|
||||||
#else
|
|
||||||
ee_printf("Total time (secs): %d\n,time_in_secs(total_time)");
|
|
||||||
if (time_in_secs(total_time) > 0)
|
|
||||||
ee_printf("Iterations/Sec : %d\n",default_num_contexts*results[0].iterations/time_in_secs(total_time));
|
|
||||||
#endif
|
|
||||||
if (time_in_secs(total_time) < 10) {
|
|
||||||
ee_printf("ERROR! Must execute for at least 10 secs for a valid result!\n");
|
|
||||||
total_errors++;
|
|
||||||
}
|
|
||||||
|
|
||||||
ee_printf("Iterations : %lu\n", (long unsigned) default_num_contexts*results[0].iterations);
|
switch (seedcrc)
|
||||||
ee_printf("Compiler version : %s\n",COMPILER_VERSION);
|
{ /* test known output for common seeds */
|
||||||
ee_printf("Compiler flags : %s\n",COMPILER_FLAGS);
|
case 0x8a02: /* seed1=0, seed2=0, seed3=0x66, size 2000 per algorithm */
|
||||||
#if (MULTITHREAD>1)
|
known_id = 0;
|
||||||
ee_printf("Parallel %s : %d\n",PARALLEL_METHOD,default_num_contexts);
|
ee_printf("6k performance run parameters for coremark.\n");
|
||||||
#endif
|
break;
|
||||||
ee_printf("Memory location : %s\n",MEM_LOCATION);
|
case 0x7b05: /* seed1=0x3415, seed2=0x3415, seed3=0x66, size 2000 per
|
||||||
/* output for verification */
|
algorithm */
|
||||||
ee_printf("seedcrc : 0x%04x\n",seedcrc);
|
known_id = 1;
|
||||||
if (results[0].execs & ID_LIST)
|
ee_printf("6k validation run parameters for coremark.\n");
|
||||||
for (i=0 ; i<default_num_contexts; i++)
|
break;
|
||||||
ee_printf("[%d]crclist : 0x%04x\n",i,results[i].crclist);
|
case 0x4eaf: /* seed1=0x8, seed2=0x8, seed3=0x8, size 400 per algorithm
|
||||||
if (results[0].execs & ID_MATRIX)
|
*/
|
||||||
for (i=0 ; i<default_num_contexts; i++)
|
known_id = 2;
|
||||||
ee_printf("[%d]crcmatrix : 0x%04x\n",i,results[i].crcmatrix);
|
ee_printf("Profile generation run parameters for coremark.\n");
|
||||||
if (results[0].execs & ID_STATE)
|
break;
|
||||||
for (i=0 ; i<default_num_contexts; i++)
|
case 0xe9f5: /* seed1=0, seed2=0, seed3=0x66, size 666 per algorithm */
|
||||||
ee_printf("[%d]crcstate : 0x%04x\n",i,results[i].crcstate);
|
known_id = 3;
|
||||||
for (i=0 ; i<default_num_contexts; i++)
|
ee_printf("2K performance run parameters for coremark.\n");
|
||||||
ee_printf("[%d]crcfinal : 0x%04x\n",i,results[i].crc);
|
break;
|
||||||
if (total_errors==0) {
|
case 0x18f2: /* seed1=0x3415, seed2=0x3415, seed3=0x66, size 666 per
|
||||||
ee_printf("Correct operation validated. See README.md for run and reporting rules.\n");
|
algorithm */
|
||||||
|
known_id = 4;
|
||||||
|
ee_printf("2K validation run parameters for coremark.\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
total_errors = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (known_id >= 0)
|
||||||
|
{
|
||||||
|
for (i = 0; i < default_num_contexts; i++)
|
||||||
|
{
|
||||||
|
results[i].err = 0;
|
||||||
|
if ((results[i].execs & ID_LIST)
|
||||||
|
&& (results[i].crclist != list_known_crc[known_id]))
|
||||||
|
{
|
||||||
|
ee_printf("[%u]ERROR! list crc 0x%04x - should be 0x%04x\n",
|
||||||
|
i,
|
||||||
|
results[i].crclist,
|
||||||
|
list_known_crc[known_id]);
|
||||||
|
results[i].err++;
|
||||||
|
}
|
||||||
|
if ((results[i].execs & ID_MATRIX)
|
||||||
|
&& (results[i].crcmatrix != matrix_known_crc[known_id]))
|
||||||
|
{
|
||||||
|
ee_printf("[%u]ERROR! matrix crc 0x%04x - should be 0x%04x\n",
|
||||||
|
i,
|
||||||
|
results[i].crcmatrix,
|
||||||
|
matrix_known_crc[known_id]);
|
||||||
|
results[i].err++;
|
||||||
|
}
|
||||||
|
if ((results[i].execs & ID_STATE)
|
||||||
|
&& (results[i].crcstate != state_known_crc[known_id]))
|
||||||
|
{
|
||||||
|
ee_printf("[%u]ERROR! state crc 0x%04x - should be 0x%04x\n",
|
||||||
|
i,
|
||||||
|
results[i].crcstate,
|
||||||
|
state_known_crc[known_id]);
|
||||||
|
results[i].err++;
|
||||||
|
}
|
||||||
|
total_errors += results[i].err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
total_errors += check_data_types();
|
||||||
|
/* and report results */
|
||||||
|
ee_printf("CoreMark Size : %lu\n", (long unsigned)results[0].size);
|
||||||
|
ee_printf("Total ticks : %lu\n", (long unsigned)total_time);
|
||||||
#if HAS_FLOAT
|
#if HAS_FLOAT
|
||||||
if (known_id==3) {
|
ee_printf("Total time (secs): %f\n", time_in_secs(total_time));
|
||||||
unsigned long long tmp = (unsigned long long) 1000.0*default_num_contexts*results[0].iterations/time_in_secs(total_time);
|
if (time_in_secs(total_time) > 0)
|
||||||
|
ee_printf("Iterations/Sec : %f\n",
|
||||||
|
default_num_contexts * results[0].iterations
|
||||||
|
/ time_in_secs(total_time));
|
||||||
|
#else
|
||||||
|
ee_printf("Total time (secs): %d\n", time_in_secs(total_time));
|
||||||
|
if (time_in_secs(total_time) > 0)
|
||||||
|
ee_printf("Iterations/Sec : %d\n",
|
||||||
|
default_num_contexts * results[0].iterations
|
||||||
|
/ time_in_secs(total_time));
|
||||||
|
#endif
|
||||||
|
if (time_in_secs(total_time) < 10)
|
||||||
|
{
|
||||||
|
ee_printf(
|
||||||
|
"ERROR! Must execute for at least 10 secs for a valid result!\n");
|
||||||
|
total_errors++;
|
||||||
|
}
|
||||||
|
|
||||||
|
ee_printf("Iterations : %lu\n",
|
||||||
|
(long unsigned)default_num_contexts * results[0].iterations);
|
||||||
|
ee_printf("Compiler version : %s\n", COMPILER_VERSION);
|
||||||
|
ee_printf("Compiler flags : %s\n", COMPILER_FLAGS);
|
||||||
|
#if (MULTITHREAD > 1)
|
||||||
|
ee_printf("Parallel %s : %d\n", PARALLEL_METHOD, default_num_contexts);
|
||||||
|
#endif
|
||||||
|
ee_printf("Memory location : %s\n", MEM_LOCATION);
|
||||||
|
/* output for verification */
|
||||||
|
ee_printf("seedcrc : 0x%04x\n", seedcrc);
|
||||||
|
if (results[0].execs & ID_LIST)
|
||||||
|
for (i = 0; i < default_num_contexts; i++)
|
||||||
|
ee_printf("[%d]crclist : 0x%04x\n", i, results[i].crclist);
|
||||||
|
if (results[0].execs & ID_MATRIX)
|
||||||
|
for (i = 0; i < default_num_contexts; i++)
|
||||||
|
ee_printf("[%d]crcmatrix : 0x%04x\n", i, results[i].crcmatrix);
|
||||||
|
if (results[0].execs & ID_STATE)
|
||||||
|
for (i = 0; i < default_num_contexts; i++)
|
||||||
|
ee_printf("[%d]crcstate : 0x%04x\n", i, results[i].crcstate);
|
||||||
|
for (i = 0; i < default_num_contexts; i++)
|
||||||
|
ee_printf("[%d]crcfinal : 0x%04x\n", i, results[i].crc);
|
||||||
|
if (total_errors == 0)
|
||||||
|
{
|
||||||
|
ee_printf(
|
||||||
|
"Correct operation validated. See README.md for run and reporting "
|
||||||
|
"rules.\n");
|
||||||
|
#if HAS_FLOAT
|
||||||
|
if (known_id == 3)
|
||||||
|
{
|
||||||
|
unsigned long long tmp = (unsigned long long) 1000.0*default_num_contexts*results[0].iterations/time_in_secs(total_time);
|
||||||
secs_ret totalmsecs = time_in_secs(total_time);
|
secs_ret totalmsecs = time_in_secs(total_time);
|
||||||
int totalmint = (int) totalmsecs;
|
int totalmint = (int) totalmsecs;
|
||||||
ee_printf("ELAPSED TIME: %d\n", totalmint);
|
ee_printf("ELAPSED TIME: %d\n", totalmint);
|
||||||
|
|
||||||
ee_printf("CoreMark 1.0 : %d / %s %s\n",tmp,COMPILER_VERSION,COMPILER_FLAGS);
|
ee_printf("CoreMark 1.0 : %d / %s %s",
|
||||||
|
tmp,
|
||||||
|
COMPILER_VERSION,
|
||||||
|
COMPILER_FLAGS);
|
||||||
#if defined(MEM_LOCATION) && !defined(MEM_LOCATION_UNSPEC)
|
#if defined(MEM_LOCATION) && !defined(MEM_LOCATION_UNSPEC)
|
||||||
ee_printf(" / %s",MEM_LOCATION);
|
ee_printf(" / %s", MEM_LOCATION);
|
||||||
#else
|
#else
|
||||||
ee_printf(" / %s",mem_name[MEM_METHOD]);
|
ee_printf(" / %s", mem_name[MEM_METHOD]);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (MULTITHREAD>1)
|
#if (MULTITHREAD > 1)
|
||||||
ee_printf(" / %d:%s",default_num_contexts,PARALLEL_METHOD);
|
ee_printf(" / %d:%s", default_num_contexts, PARALLEL_METHOD);
|
||||||
#endif
|
#endif
|
||||||
ee_printf("\n");
|
ee_printf("\n");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
if (total_errors>0)
|
if (total_errors > 0)
|
||||||
ee_printf("Errors detected\n");
|
ee_printf("Errors detected\n");
|
||||||
if (total_errors<0)
|
if (total_errors < 0)
|
||||||
ee_printf("Cannot validate operation for these seed values, please compare with results on a known platform.\n");
|
ee_printf(
|
||||||
|
"Cannot validate operation for these seed values, please compare "
|
||||||
|
"with results on a known platform.\n");
|
||||||
|
|
||||||
#if (MEM_METHOD==MEM_MALLOC)
|
#if (MEM_METHOD == MEM_MALLOC)
|
||||||
for (i=0 ; i<MULTITHREAD; i++)
|
for (i = 0; i < MULTITHREAD; i++)
|
||||||
portable_free(results[i].memblock[0]);
|
portable_free(results[i].memblock[0]);
|
||||||
#endif
|
#endif
|
||||||
/* And last call any target specific code for finalizing */
|
/* And last call any target specific code for finalizing */
|
||||||
portable_fini(&(results[0].port));
|
portable_fini(&(results[0].port));
|
||||||
|
|
||||||
return MAIN_RETURN_VAL;
|
return MAIN_RETURN_VAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
//pls
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -19,290 +19,341 @@ Original Author: Shay Gal-on
|
|||||||
#include "coremark.h"
|
#include "coremark.h"
|
||||||
/*
|
/*
|
||||||
Topic: Description
|
Topic: Description
|
||||||
Matrix manipulation benchmark
|
Matrix manipulation benchmark
|
||||||
|
|
||||||
This very simple algorithm forms the basis of many more complex algorithms.
|
|
||||||
|
|
||||||
The tight inner loop is the focus of many optimizations (compiler as well as hardware based)
|
|
||||||
and is thus relevant for embedded processing.
|
|
||||||
|
|
||||||
The total available data space will be divided to 3 parts:
|
|
||||||
NxN Matrix A - initialized with small values (upper 3/4 of the bits all zero).
|
|
||||||
NxN Matrix B - initialized with medium values (upper half of the bits all zero).
|
|
||||||
NxN Matrix C - used for the result.
|
|
||||||
|
|
||||||
The actual values for A and B must be derived based on input that is not available at compile time.
|
This very simple algorithm forms the basis of many more complex
|
||||||
|
algorithms.
|
||||||
|
|
||||||
|
The tight inner loop is the focus of many optimizations (compiler as
|
||||||
|
well as hardware based) and is thus relevant for embedded processing.
|
||||||
|
|
||||||
|
The total available data space will be divided to 3 parts:
|
||||||
|
NxN Matrix A - initialized with small values (upper 3/4 of the bits all
|
||||||
|
zero). NxN Matrix B - initialized with medium values (upper half of the bits all
|
||||||
|
zero). NxN Matrix C - used for the result.
|
||||||
|
|
||||||
|
The actual values for A and B must be derived based on input that is not
|
||||||
|
available at compile time.
|
||||||
*/
|
*/
|
||||||
ee_s16 matrix_test(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B, MATDAT val);
|
ee_s16 matrix_test(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B, MATDAT val);
|
||||||
ee_s16 matrix_sum(ee_u32 N, MATRES *C, MATDAT clipval);
|
ee_s16 matrix_sum(ee_u32 N, MATRES *C, MATDAT clipval);
|
||||||
void matrix_mul_const(ee_u32 N, MATRES *C, MATDAT *A, MATDAT val);
|
void matrix_mul_const(ee_u32 N, MATRES *C, MATDAT *A, MATDAT val);
|
||||||
void matrix_mul_vect(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B);
|
void matrix_mul_vect(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B);
|
||||||
void matrix_mul_matrix(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B);
|
void matrix_mul_matrix(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B);
|
||||||
void matrix_mul_matrix_bitextract(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B);
|
void matrix_mul_matrix_bitextract(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B);
|
||||||
void matrix_add_const(ee_u32 N, MATDAT *A, MATDAT val);
|
void matrix_add_const(ee_u32 N, MATDAT *A, MATDAT val);
|
||||||
|
|
||||||
#define matrix_test_next(x) (x+1)
|
#define matrix_test_next(x) (x + 1)
|
||||||
#define matrix_clip(x,y) ((y) ? (x) & 0x0ff : (x) & 0x0ffff)
|
#define matrix_clip(x, y) ((y) ? (x)&0x0ff : (x)&0x0ffff)
|
||||||
#define matrix_big(x) (0xf000 | (x))
|
#define matrix_big(x) (0xf000 | (x))
|
||||||
#define bit_extract(x,from,to) (((x)>>(from)) & (~(0xffffffff << (to))))
|
#define bit_extract(x, from, to) (((x) >> (from)) & (~(0xffffffff << (to))))
|
||||||
|
|
||||||
#if CORE_DEBUG
|
#if CORE_DEBUG
|
||||||
void printmat(MATDAT *A, ee_u32 N, char *name) {
|
void
|
||||||
ee_u32 i,j;
|
printmat(MATDAT *A, ee_u32 N, char *name)
|
||||||
ee_printf("Matrix %s [%dx%d]:\n",name,N,N);
|
{
|
||||||
for (i=0; i<N; i++) {
|
ee_u32 i, j;
|
||||||
for (j=0; j<N; j++) {
|
ee_printf("Matrix %s [%dx%d]:\n", name, N, N);
|
||||||
if (j!=0)
|
for (i = 0; i < N; i++)
|
||||||
ee_printf(",");
|
{
|
||||||
ee_printf("%d",A[i*N+j]);
|
for (j = 0; j < N; j++)
|
||||||
}
|
{
|
||||||
ee_printf("\n");
|
if (j != 0)
|
||||||
}
|
ee_printf(",");
|
||||||
|
ee_printf("%d", A[i * N + j]);
|
||||||
|
}
|
||||||
|
ee_printf("\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
void printmatC(MATRES *C, ee_u32 N, char *name) {
|
void
|
||||||
ee_u32 i,j;
|
printmatC(MATRES *C, ee_u32 N, char *name)
|
||||||
ee_printf("Matrix %s [%dx%d]:\n",name,N,N);
|
{
|
||||||
for (i=0; i<N; i++) {
|
ee_u32 i, j;
|
||||||
for (j=0; j<N; j++) {
|
ee_printf("Matrix %s [%dx%d]:\n", name, N, N);
|
||||||
if (j!=0)
|
for (i = 0; i < N; i++)
|
||||||
ee_printf(",");
|
{
|
||||||
ee_printf("%d",C[i*N+j]);
|
for (j = 0; j < N; j++)
|
||||||
}
|
{
|
||||||
ee_printf("\n");
|
if (j != 0)
|
||||||
}
|
ee_printf(",");
|
||||||
|
ee_printf("%d", C[i * N + j]);
|
||||||
|
}
|
||||||
|
ee_printf("\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
/* Function: core_bench_matrix
|
/* Function: core_bench_matrix
|
||||||
Benchmark function
|
Benchmark function
|
||||||
|
|
||||||
Iterate <matrix_test> N times,
|
Iterate <matrix_test> N times,
|
||||||
changing the matrix values slightly by a constant amount each time.
|
changing the matrix values slightly by a constant amount each time.
|
||||||
*/
|
*/
|
||||||
ee_u16 core_bench_matrix(mat_params *p, ee_s16 seed, ee_u16 crc) {
|
ee_u16
|
||||||
ee_u32 N=p->N;
|
core_bench_matrix(mat_params *p, ee_s16 seed, ee_u16 crc)
|
||||||
MATRES *C=p->C;
|
{
|
||||||
MATDAT *A=p->A;
|
ee_u32 N = p->N;
|
||||||
MATDAT *B=p->B;
|
MATRES *C = p->C;
|
||||||
MATDAT val=(MATDAT)seed;
|
MATDAT *A = p->A;
|
||||||
|
MATDAT *B = p->B;
|
||||||
|
MATDAT val = (MATDAT)seed;
|
||||||
|
|
||||||
crc=crc16(matrix_test(N,C,A,B,val),crc);
|
crc = crc16(matrix_test(N, C, A, B, val), crc);
|
||||||
|
|
||||||
return crc;
|
return crc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Function: matrix_test
|
/* Function: matrix_test
|
||||||
Perform matrix manipulation.
|
Perform matrix manipulation.
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
N - Dimensions of the matrix.
|
N - Dimensions of the matrix.
|
||||||
C - memory for result matrix.
|
C - memory for result matrix.
|
||||||
A - input matrix
|
A - input matrix
|
||||||
B - operator matrix (not changed during operations)
|
B - operator matrix (not changed during operations)
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
A CRC value that captures all results calculated in the function.
|
A CRC value that captures all results calculated in the function.
|
||||||
In particular, crc of the value calculated on the result matrix
|
In particular, crc of the value calculated on the result matrix
|
||||||
after each step by <matrix_sum>.
|
after each step by <matrix_sum>.
|
||||||
|
|
||||||
Operation:
|
Operation:
|
||||||
|
|
||||||
1 - Add a constant value to all elements of a matrix.
|
|
||||||
2 - Multiply a matrix by a constant.
|
|
||||||
3 - Multiply a matrix by a vector.
|
|
||||||
4 - Multiply a matrix by a matrix.
|
|
||||||
5 - Add a constant value to all elements of a matrix.
|
|
||||||
|
|
||||||
After the last step, matrix A is back to original contents.
|
1 - Add a constant value to all elements of a matrix.
|
||||||
|
2 - Multiply a matrix by a constant.
|
||||||
|
3 - Multiply a matrix by a vector.
|
||||||
|
4 - Multiply a matrix by a matrix.
|
||||||
|
5 - Add a constant value to all elements of a matrix.
|
||||||
|
|
||||||
|
After the last step, matrix A is back to original contents.
|
||||||
*/
|
*/
|
||||||
ee_s16 matrix_test(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B, MATDAT val) {
|
ee_s16
|
||||||
ee_u16 crc=0;
|
matrix_test(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B, MATDAT val)
|
||||||
MATDAT clipval=matrix_big(val);
|
{
|
||||||
|
ee_u16 crc = 0;
|
||||||
|
MATDAT clipval = matrix_big(val);
|
||||||
|
|
||||||
matrix_add_const(N,A,val); /* make sure data changes */
|
matrix_add_const(N, A, val); /* make sure data changes */
|
||||||
#if CORE_DEBUG
|
#if CORE_DEBUG
|
||||||
printmat(A,N,"matrix_add_const");
|
printmat(A, N, "matrix_add_const");
|
||||||
#endif
|
#endif
|
||||||
matrix_mul_const(N,C,A,val);
|
matrix_mul_const(N, C, A, val);
|
||||||
crc=crc16(matrix_sum(N,C,clipval),crc);
|
crc = crc16(matrix_sum(N, C, clipval), crc);
|
||||||
#if CORE_DEBUG
|
#if CORE_DEBUG
|
||||||
printmatC(C,N,"matrix_mul_const");
|
printmatC(C, N, "matrix_mul_const");
|
||||||
#endif
|
#endif
|
||||||
matrix_mul_vect(N,C,A,B);
|
matrix_mul_vect(N, C, A, B);
|
||||||
crc=crc16(matrix_sum(N,C,clipval),crc);
|
crc = crc16(matrix_sum(N, C, clipval), crc);
|
||||||
#if CORE_DEBUG
|
#if CORE_DEBUG
|
||||||
printmatC(C,N,"matrix_mul_vect");
|
printmatC(C, N, "matrix_mul_vect");
|
||||||
#endif
|
#endif
|
||||||
matrix_mul_matrix(N,C,A,B);
|
matrix_mul_matrix(N, C, A, B);
|
||||||
crc=crc16(matrix_sum(N,C,clipval),crc);
|
crc = crc16(matrix_sum(N, C, clipval), crc);
|
||||||
#if CORE_DEBUG
|
#if CORE_DEBUG
|
||||||
printmatC(C,N,"matrix_mul_matrix");
|
printmatC(C, N, "matrix_mul_matrix");
|
||||||
#endif
|
#endif
|
||||||
matrix_mul_matrix_bitextract(N,C,A,B);
|
matrix_mul_matrix_bitextract(N, C, A, B);
|
||||||
crc=crc16(matrix_sum(N,C,clipval),crc);
|
crc = crc16(matrix_sum(N, C, clipval), crc);
|
||||||
#if CORE_DEBUG
|
#if CORE_DEBUG
|
||||||
printmatC(C,N,"matrix_mul_matrix_bitextract");
|
printmatC(C, N, "matrix_mul_matrix_bitextract");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
matrix_add_const(N,A,-val); /* return matrix to initial value */
|
matrix_add_const(N, A, -val); /* return matrix to initial value */
|
||||||
return crc;
|
return crc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Function : matrix_init
|
/* Function : matrix_init
|
||||||
Initialize the memory block for matrix benchmarking.
|
Initialize the memory block for matrix benchmarking.
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
blksize - Size of memory to be initialized.
|
blksize - Size of memory to be initialized.
|
||||||
memblk - Pointer to memory block.
|
memblk - Pointer to memory block.
|
||||||
seed - Actual values chosen depend on the seed parameter.
|
seed - Actual values chosen depend on the seed parameter.
|
||||||
p - pointers to <mat_params> containing initialized matrixes.
|
p - pointers to <mat_params> containing initialized matrixes.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Matrix dimensions.
|
Matrix dimensions.
|
||||||
|
|
||||||
Note:
|
Note:
|
||||||
The seed parameter MUST be supplied from a source that cannot be determined at compile time
|
The seed parameter MUST be supplied from a source that cannot be
|
||||||
|
determined at compile time
|
||||||
*/
|
*/
|
||||||
ee_u32 core_init_matrix(ee_u32 blksize, void *memblk, ee_s32 seed, mat_params *p) {
|
ee_u32
|
||||||
ee_u32 N=0;
|
core_init_matrix(ee_u32 blksize, void *memblk, ee_s32 seed, mat_params *p)
|
||||||
MATDAT *A;
|
{
|
||||||
MATDAT *B;
|
ee_u32 N = 0;
|
||||||
ee_s32 order=1;
|
MATDAT *A;
|
||||||
MATDAT val;
|
MATDAT *B;
|
||||||
ee_u32 i=0,j=0;
|
ee_s32 order = 1;
|
||||||
if (seed==0)
|
MATDAT val;
|
||||||
seed=1;
|
ee_u32 i = 0, j = 0;
|
||||||
while (j<blksize) {
|
if (seed == 0)
|
||||||
i++;
|
seed = 1;
|
||||||
j=i*i*2*4;
|
while (j < blksize)
|
||||||
}
|
{
|
||||||
N=i-1;
|
i++;
|
||||||
A=(MATDAT *)align_mem(memblk);
|
j = i * i * 2 * 4;
|
||||||
B=A+N*N;
|
}
|
||||||
|
N = i - 1;
|
||||||
|
A = (MATDAT *)align_mem(memblk);
|
||||||
|
B = A + N * N;
|
||||||
|
|
||||||
for (i=0; i<N; i++) {
|
for (i = 0; i < N; i++)
|
||||||
for (j=0; j<N; j++) {
|
{
|
||||||
seed = ( ( order * seed ) % 65536 );
|
for (j = 0; j < N; j++)
|
||||||
val = (seed + order);
|
{
|
||||||
val=matrix_clip(val,0);
|
seed = ((order * seed) % 65536);
|
||||||
B[i*N+j] = val;
|
val = (seed + order);
|
||||||
val = (val + order);
|
val = matrix_clip(val, 0);
|
||||||
val=matrix_clip(val,1);
|
B[i * N + j] = val;
|
||||||
A[i*N+j] = val;
|
val = (val + order);
|
||||||
order++;
|
val = matrix_clip(val, 1);
|
||||||
}
|
A[i * N + j] = val;
|
||||||
}
|
order++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
p->A=A;
|
p->A = A;
|
||||||
p->B=B;
|
p->B = B;
|
||||||
p->C=(MATRES *)align_mem(B+N*N);
|
p->C = (MATRES *)align_mem(B + N * N);
|
||||||
p->N=N;
|
p->N = N;
|
||||||
#if CORE_DEBUG
|
#if CORE_DEBUG
|
||||||
printmat(A,N,"A");
|
printmat(A, N, "A");
|
||||||
printmat(B,N,"B");
|
printmat(B, N, "B");
|
||||||
#endif
|
#endif
|
||||||
return N;
|
return N;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Function: matrix_sum
|
/* Function: matrix_sum
|
||||||
Calculate a function that depends on the values of elements in the matrix.
|
Calculate a function that depends on the values of elements in the
|
||||||
|
matrix.
|
||||||
|
|
||||||
For each element, accumulate into a temporary variable.
|
For each element, accumulate into a temporary variable.
|
||||||
|
|
||||||
As long as this value is under the parameter clipval,
|
As long as this value is under the parameter clipval,
|
||||||
add 1 to the result if the element is bigger then the previous.
|
add 1 to the result if the element is bigger then the previous.
|
||||||
|
|
||||||
Otherwise, reset the accumulator and add 10 to the result.
|
Otherwise, reset the accumulator and add 10 to the result.
|
||||||
*/
|
*/
|
||||||
ee_s16 matrix_sum(ee_u32 N, MATRES *C, MATDAT clipval) {
|
ee_s16
|
||||||
MATRES tmp=0,prev=0,cur=0;
|
matrix_sum(ee_u32 N, MATRES *C, MATDAT clipval)
|
||||||
ee_s16 ret=0;
|
{
|
||||||
ee_u32 i,j;
|
MATRES tmp = 0, prev = 0, cur = 0;
|
||||||
for (i=0; i<N; i++) {
|
ee_s16 ret = 0;
|
||||||
for (j=0; j<N; j++) {
|
ee_u32 i, j;
|
||||||
cur=C[i*N+j];
|
for (i = 0; i < N; i++)
|
||||||
tmp+=cur;
|
{
|
||||||
if (tmp>clipval) {
|
for (j = 0; j < N; j++)
|
||||||
ret+=10;
|
{
|
||||||
tmp=0;
|
cur = C[i * N + j];
|
||||||
} else {
|
tmp += cur;
|
||||||
ret += (cur>prev) ? 1 : 0;
|
if (tmp > clipval)
|
||||||
}
|
{
|
||||||
prev=cur;
|
ret += 10;
|
||||||
}
|
tmp = 0;
|
||||||
}
|
}
|
||||||
return ret;
|
else
|
||||||
|
{
|
||||||
|
ret += (cur > prev) ? 1 : 0;
|
||||||
|
}
|
||||||
|
prev = cur;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Function: matrix_mul_const
|
/* Function: matrix_mul_const
|
||||||
Multiply a matrix by a constant.
|
Multiply a matrix by a constant.
|
||||||
This could be used as a scaler for instance.
|
This could be used as a scaler for instance.
|
||||||
*/
|
*/
|
||||||
void matrix_mul_const(ee_u32 N, MATRES *C, MATDAT *A, MATDAT val) {
|
void
|
||||||
ee_u32 i,j;
|
matrix_mul_const(ee_u32 N, MATRES *C, MATDAT *A, MATDAT val)
|
||||||
for (i=0; i<N; i++) {
|
{
|
||||||
for (j=0; j<N; j++) {
|
ee_u32 i, j;
|
||||||
C[i*N+j]=(MATRES)A[i*N+j] * (MATRES)val;
|
for (i = 0; i < N; i++)
|
||||||
}
|
{
|
||||||
}
|
for (j = 0; j < N; j++)
|
||||||
|
{
|
||||||
|
C[i * N + j] = (MATRES)A[i * N + j] * (MATRES)val;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Function: matrix_add_const
|
/* Function: matrix_add_const
|
||||||
Add a constant value to all elements of a matrix.
|
Add a constant value to all elements of a matrix.
|
||||||
*/
|
*/
|
||||||
void matrix_add_const(ee_u32 N, MATDAT *A, MATDAT val) {
|
void
|
||||||
ee_u32 i,j;
|
matrix_add_const(ee_u32 N, MATDAT *A, MATDAT val)
|
||||||
for (i=0; i<N; i++) {
|
{
|
||||||
for (j=0; j<N; j++) {
|
ee_u32 i, j;
|
||||||
A[i*N+j] += val;
|
for (i = 0; i < N; i++)
|
||||||
}
|
{
|
||||||
}
|
for (j = 0; j < N; j++)
|
||||||
|
{
|
||||||
|
A[i * N + j] += val;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Function: matrix_mul_vect
|
/* Function: matrix_mul_vect
|
||||||
Multiply a matrix by a vector.
|
Multiply a matrix by a vector.
|
||||||
This is common in many simple filters (e.g. fir where a vector of coefficients is applied to the matrix.)
|
This is common in many simple filters (e.g. fir where a vector of
|
||||||
|
coefficients is applied to the matrix.)
|
||||||
*/
|
*/
|
||||||
void matrix_mul_vect(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B) {
|
void
|
||||||
ee_u32 i,j;
|
matrix_mul_vect(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B)
|
||||||
for (i=0; i<N; i++) {
|
{
|
||||||
C[i]=0;
|
ee_u32 i, j;
|
||||||
for (j=0; j<N; j++) {
|
for (i = 0; i < N; i++)
|
||||||
C[i]+=(MATRES)A[i*N+j] * (MATRES)B[j];
|
{
|
||||||
}
|
C[i] = 0;
|
||||||
}
|
for (j = 0; j < N; j++)
|
||||||
|
{
|
||||||
|
C[i] += (MATRES)A[i * N + j] * (MATRES)B[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Function: matrix_mul_matrix
|
/* Function: matrix_mul_matrix
|
||||||
Multiply a matrix by a matrix.
|
Multiply a matrix by a matrix.
|
||||||
Basic code is used in many algorithms, mostly with minor changes such as scaling.
|
Basic code is used in many algorithms, mostly with minor changes such as
|
||||||
|
scaling.
|
||||||
*/
|
*/
|
||||||
void matrix_mul_matrix(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B) {
|
void
|
||||||
ee_u32 i,j,k;
|
matrix_mul_matrix(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B)
|
||||||
for (i=0; i<N; i++) {
|
{
|
||||||
for (j=0; j<N; j++) {
|
ee_u32 i, j, k;
|
||||||
C[i*N+j]=0;
|
for (i = 0; i < N; i++)
|
||||||
for(k=0;k<N;k++)
|
{
|
||||||
{
|
for (j = 0; j < N; j++)
|
||||||
C[i*N+j]+=(MATRES)A[i*N+k] * (MATRES)B[k*N+j];
|
{
|
||||||
}
|
C[i * N + j] = 0;
|
||||||
}
|
for (k = 0; k < N; k++)
|
||||||
}
|
{
|
||||||
|
C[i * N + j] += (MATRES)A[i * N + k] * (MATRES)B[k * N + j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Function: matrix_mul_matrix_bitextract
|
/* Function: matrix_mul_matrix_bitextract
|
||||||
Multiply a matrix by a matrix, and extract some bits from the result.
|
Multiply a matrix by a matrix, and extract some bits from the result.
|
||||||
Basic code is used in many algorithms, mostly with minor changes such as scaling.
|
Basic code is used in many algorithms, mostly with minor changes such as
|
||||||
|
scaling.
|
||||||
*/
|
*/
|
||||||
void matrix_mul_matrix_bitextract(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B) {
|
void
|
||||||
ee_u32 i,j,k;
|
matrix_mul_matrix_bitextract(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B)
|
||||||
for (i=0; i<N; i++) {
|
{
|
||||||
for (j=0; j<N; j++) {
|
ee_u32 i, j, k;
|
||||||
C[i*N+j]=0;
|
for (i = 0; i < N; i++)
|
||||||
for(k=0;k<N;k++)
|
{
|
||||||
{
|
for (j = 0; j < N; j++)
|
||||||
MATRES tmp=(MATRES)A[i*N+k] * (MATRES)B[k*N+j];
|
{
|
||||||
C[i*N+j]+=bit_extract(tmp,2,4)*bit_extract(tmp,5,7);
|
C[i * N + j] = 0;
|
||||||
}
|
for (k = 0; k < N; k++)
|
||||||
}
|
{
|
||||||
}
|
MATRES tmp = (MATRES)A[i * N + k] * (MATRES)B[k * N + j];
|
||||||
|
C[i * N + j] += bit_extract(tmp, 2, 4) * bit_extract(tmp, 5, 7);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,260 +18,313 @@ Original Author: Shay Gal-on
|
|||||||
|
|
||||||
#include "coremark.h"
|
#include "coremark.h"
|
||||||
/* local functions */
|
/* local functions */
|
||||||
enum CORE_STATE core_state_transition( ee_u8 **instr , ee_u32 *transition_count);
|
enum CORE_STATE core_state_transition(ee_u8 **instr, ee_u32 *transition_count);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Topic: Description
|
Topic: Description
|
||||||
Simple state machines like this one are used in many embedded products.
|
Simple state machines like this one are used in many embedded products.
|
||||||
|
|
||||||
For more complex state machines, sometimes a state transition table implementation is used instead,
|
For more complex state machines, sometimes a state transition table
|
||||||
trading speed of direct coding for ease of maintenance.
|
implementation is used instead, trading speed of direct coding for ease of
|
||||||
|
maintenance.
|
||||||
Since the main goal of using a state machine in CoreMark is to excercise the switch/if behaviour,
|
|
||||||
we are using a small moore machine.
|
Since the main goal of using a state machine in CoreMark is to excercise
|
||||||
|
the switch/if behaviour, we are using a small moore machine.
|
||||||
In particular, this machine tests type of string input,
|
|
||||||
trying to determine whether the input is a number or something else.
|
In particular, this machine tests type of string input,
|
||||||
(see core_state.png).
|
trying to determine whether the input is a number or something else.
|
||||||
|
(see core_state.png).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Function: core_bench_state
|
/* Function: core_bench_state
|
||||||
Benchmark function
|
Benchmark function
|
||||||
|
|
||||||
Go over the input twice, once direct, and once after introducing some corruption.
|
Go over the input twice, once direct, and once after introducing some
|
||||||
|
corruption.
|
||||||
*/
|
*/
|
||||||
ee_u16 core_bench_state(ee_u32 blksize, ee_u8 *memblock,
|
ee_u16
|
||||||
ee_s16 seed1, ee_s16 seed2, ee_s16 step, ee_u16 crc)
|
core_bench_state(ee_u32 blksize,
|
||||||
|
ee_u8 *memblock,
|
||||||
|
ee_s16 seed1,
|
||||||
|
ee_s16 seed2,
|
||||||
|
ee_s16 step,
|
||||||
|
ee_u16 crc)
|
||||||
{
|
{
|
||||||
ee_u32 final_counts[NUM_CORE_STATES];
|
ee_u32 final_counts[NUM_CORE_STATES];
|
||||||
ee_u32 track_counts[NUM_CORE_STATES];
|
ee_u32 track_counts[NUM_CORE_STATES];
|
||||||
ee_u8 *p=memblock;
|
ee_u8 *p = memblock;
|
||||||
ee_u32 i;
|
ee_u32 i;
|
||||||
|
|
||||||
|
|
||||||
#if CORE_DEBUG
|
#if CORE_DEBUG
|
||||||
ee_printf("State Bench: %d,%d,%d,%04x\n",seed1,seed2,step,crc);
|
ee_printf("State Bench: %d,%d,%d,%04x\n", seed1, seed2, step, crc);
|
||||||
#endif
|
#endif
|
||||||
for (i=0; i<NUM_CORE_STATES; i++) {
|
for (i = 0; i < NUM_CORE_STATES; i++)
|
||||||
final_counts[i]=track_counts[i]=0;
|
{
|
||||||
}
|
final_counts[i] = track_counts[i] = 0;
|
||||||
/* run the state machine over the input */
|
}
|
||||||
while (*p!=0) {
|
/* run the state machine over the input */
|
||||||
enum CORE_STATE fstate=core_state_transition(&p,track_counts);
|
while (*p != 0)
|
||||||
final_counts[fstate]++;
|
{
|
||||||
|
enum CORE_STATE fstate = core_state_transition(&p, track_counts);
|
||||||
|
final_counts[fstate]++;
|
||||||
#if CORE_DEBUG
|
#if CORE_DEBUG
|
||||||
ee_printf("%d,",fstate);
|
ee_printf("%d,", fstate);
|
||||||
}
|
}
|
||||||
ee_printf("\n");
|
ee_printf("\n");
|
||||||
#else
|
#else
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
p=memblock;
|
p = memblock;
|
||||||
while (p < (memblock+blksize)) { /* insert some corruption */
|
while (p < (memblock + blksize))
|
||||||
if (*p!=',')
|
{ /* insert some corruption */
|
||||||
*p^=(ee_u8)seed1;
|
if (*p != ',')
|
||||||
p+=step;
|
*p ^= (ee_u8)seed1;
|
||||||
}
|
p += step;
|
||||||
p=memblock;
|
}
|
||||||
/* run the state machine over the input again */
|
p = memblock;
|
||||||
while (*p!=0) {
|
/* run the state machine over the input again */
|
||||||
enum CORE_STATE fstate=core_state_transition(&p,track_counts);
|
while (*p != 0)
|
||||||
final_counts[fstate]++;
|
{
|
||||||
|
enum CORE_STATE fstate = core_state_transition(&p, track_counts);
|
||||||
|
final_counts[fstate]++;
|
||||||
#if CORE_DEBUG
|
#if CORE_DEBUG
|
||||||
ee_printf("%d,",fstate);
|
ee_printf("%d,", fstate);
|
||||||
}
|
}
|
||||||
ee_printf("\n");
|
ee_printf("\n");
|
||||||
#else
|
#else
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
p=memblock;
|
p = memblock;
|
||||||
while (p < (memblock+blksize)) { /* undo corruption is seed1 and seed2 are equal */
|
while (p < (memblock + blksize))
|
||||||
if (*p!=',')
|
{ /* undo corruption is seed1 and seed2 are equal */
|
||||||
*p^=(ee_u8)seed2;
|
if (*p != ',')
|
||||||
p+=step;
|
*p ^= (ee_u8)seed2;
|
||||||
}
|
p += step;
|
||||||
/* end timing */
|
}
|
||||||
for (i=0; i<NUM_CORE_STATES; i++) {
|
/* end timing */
|
||||||
crc=crcu32(final_counts[i],crc);
|
for (i = 0; i < NUM_CORE_STATES; i++)
|
||||||
crc=crcu32(track_counts[i],crc);
|
{
|
||||||
}
|
crc = crcu32(final_counts[i], crc);
|
||||||
return crc;
|
crc = crcu32(track_counts[i], crc);
|
||||||
|
}
|
||||||
|
return crc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Default initialization patterns */
|
/* Default initialization patterns */
|
||||||
static ee_u8 *intpat[4] ={(ee_u8 *)"5012",(ee_u8 *)"1234",(ee_u8 *)"-874",(ee_u8 *)"+122"};
|
static ee_u8 *intpat[4]
|
||||||
static ee_u8 *floatpat[4]={(ee_u8 *)"35.54400",(ee_u8 *)".1234500",(ee_u8 *)"-110.700",(ee_u8 *)"+0.64400"};
|
= { (ee_u8 *)"5012", (ee_u8 *)"1234", (ee_u8 *)"-874", (ee_u8 *)"+122" };
|
||||||
static ee_u8 *scipat[4] ={(ee_u8 *)"5.500e+3",(ee_u8 *)"-.123e-2",(ee_u8 *)"-87e+832",(ee_u8 *)"+0.6e-12"};
|
static ee_u8 *floatpat[4] = { (ee_u8 *)"35.54400",
|
||||||
static ee_u8 *errpat[4] ={(ee_u8 *)"T0.3e-1F",(ee_u8 *)"-T.T++Tq",(ee_u8 *)"1T3.4e4z",(ee_u8 *)"34.0e-T^"};
|
(ee_u8 *)".1234500",
|
||||||
|
(ee_u8 *)"-110.700",
|
||||||
|
(ee_u8 *)"+0.64400" };
|
||||||
|
static ee_u8 *scipat[4] = { (ee_u8 *)"5.500e+3",
|
||||||
|
(ee_u8 *)"-.123e-2",
|
||||||
|
(ee_u8 *)"-87e+832",
|
||||||
|
(ee_u8 *)"+0.6e-12" };
|
||||||
|
static ee_u8 *errpat[4] = { (ee_u8 *)"T0.3e-1F",
|
||||||
|
(ee_u8 *)"-T.T++Tq",
|
||||||
|
(ee_u8 *)"1T3.4e4z",
|
||||||
|
(ee_u8 *)"34.0e-T^" };
|
||||||
|
|
||||||
/* Function: core_init_state
|
/* Function: core_init_state
|
||||||
Initialize the input data for the state machine.
|
Initialize the input data for the state machine.
|
||||||
|
|
||||||
Populate the input with several predetermined strings, interspersed.
|
Populate the input with several predetermined strings, interspersed.
|
||||||
Actual patterns chosen depend on the seed parameter.
|
Actual patterns chosen depend on the seed parameter.
|
||||||
|
|
||||||
Note:
|
Note:
|
||||||
The seed parameter MUST be supplied from a source that cannot be determined at compile time
|
The seed parameter MUST be supplied from a source that cannot be
|
||||||
|
determined at compile time
|
||||||
*/
|
*/
|
||||||
void core_init_state(ee_u32 size, ee_s16 seed, ee_u8 *p) {
|
void
|
||||||
ee_u32 total=0,next=0,i;
|
core_init_state(ee_u32 size, ee_s16 seed, ee_u8 *p)
|
||||||
ee_u8 *buf=0;
|
{
|
||||||
|
ee_u32 total = 0, next = 0, i;
|
||||||
|
ee_u8 *buf = 0;
|
||||||
#if CORE_DEBUG
|
#if CORE_DEBUG
|
||||||
ee_u8 *start=p;
|
ee_u8 *start = p;
|
||||||
ee_printf("State: %d,%d\n",size,seed);
|
ee_printf("State: %d,%d\n", size, seed);
|
||||||
#endif
|
#endif
|
||||||
size--;
|
size--;
|
||||||
next=0;
|
next = 0;
|
||||||
while ((total+next+1)<size) {
|
while ((total + next + 1) < size)
|
||||||
if (next>0) {
|
{
|
||||||
for(i=0;i<next;i++)
|
if (next > 0)
|
||||||
*(p+total+i)=buf[i];
|
{
|
||||||
*(p+total+i)=',';
|
for (i = 0; i < next; i++)
|
||||||
total+=next+1;
|
*(p + total + i) = buf[i];
|
||||||
}
|
*(p + total + i) = ',';
|
||||||
seed++;
|
total += next + 1;
|
||||||
switch (seed & 0x7) {
|
}
|
||||||
case 0: /* int */
|
seed++;
|
||||||
case 1: /* int */
|
switch (seed & 0x7)
|
||||||
case 2: /* int */
|
{
|
||||||
buf=intpat[(seed>>3) & 0x3];
|
case 0: /* int */
|
||||||
next=4;
|
case 1: /* int */
|
||||||
break;
|
case 2: /* int */
|
||||||
case 3: /* float */
|
buf = intpat[(seed >> 3) & 0x3];
|
||||||
case 4: /* float */
|
next = 4;
|
||||||
buf=floatpat[(seed>>3) & 0x3];
|
break;
|
||||||
next=8;
|
case 3: /* float */
|
||||||
break;
|
case 4: /* float */
|
||||||
case 5: /* scientific */
|
buf = floatpat[(seed >> 3) & 0x3];
|
||||||
case 6: /* scientific */
|
next = 8;
|
||||||
buf=scipat[(seed>>3) & 0x3];
|
break;
|
||||||
next=8;
|
case 5: /* scientific */
|
||||||
break;
|
case 6: /* scientific */
|
||||||
case 7: /* invalid */
|
buf = scipat[(seed >> 3) & 0x3];
|
||||||
buf=errpat[(seed>>3) & 0x3];
|
next = 8;
|
||||||
next=8;
|
break;
|
||||||
break;
|
case 7: /* invalid */
|
||||||
default: /* Never happen, just to make some compilers happy */
|
buf = errpat[(seed >> 3) & 0x3];
|
||||||
break;
|
next = 8;
|
||||||
}
|
break;
|
||||||
}
|
default: /* Never happen, just to make some compilers happy */
|
||||||
size++;
|
break;
|
||||||
while (total<size) { /* fill the rest with 0 */
|
}
|
||||||
*(p+total)=0;
|
}
|
||||||
total++;
|
size++;
|
||||||
}
|
while (total < size)
|
||||||
|
{ /* fill the rest with 0 */
|
||||||
|
*(p + total) = 0;
|
||||||
|
total++;
|
||||||
|
}
|
||||||
#if CORE_DEBUG
|
#if CORE_DEBUG
|
||||||
ee_printf("State Input: %s\n",start);
|
ee_printf("State Input: %s\n", start);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static ee_u8 ee_isdigit(ee_u8 c) {
|
static ee_u8
|
||||||
ee_u8 retval;
|
ee_isdigit(ee_u8 c)
|
||||||
retval = ((c>='0') & (c<='9')) ? 1 : 0;
|
{
|
||||||
return retval;
|
ee_u8 retval;
|
||||||
|
retval = ((c >= '0') & (c <= '9')) ? 1 : 0;
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Function: core_state_transition
|
/* Function: core_state_transition
|
||||||
Actual state machine.
|
Actual state machine.
|
||||||
|
|
||||||
The state machine will continue scanning until either:
|
The state machine will continue scanning until either:
|
||||||
1 - an invalid input is detcted.
|
1 - an invalid input is detcted.
|
||||||
2 - a valid number has been detected.
|
2 - a valid number has been detected.
|
||||||
|
|
||||||
The input pointer is updated to point to the end of the token, and the end state is returned (either specific format determined or invalid).
|
The input pointer is updated to point to the end of the token, and the
|
||||||
|
end state is returned (either specific format determined or invalid).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
enum CORE_STATE core_state_transition( ee_u8 **instr , ee_u32 *transition_count) {
|
enum CORE_STATE
|
||||||
ee_u8 *str=*instr;
|
core_state_transition(ee_u8 **instr, ee_u32 *transition_count)
|
||||||
ee_u8 NEXT_SYMBOL;
|
{
|
||||||
enum CORE_STATE state=CORE_START;
|
ee_u8 * str = *instr;
|
||||||
for( ; *str && state != CORE_INVALID; str++ ) {
|
ee_u8 NEXT_SYMBOL;
|
||||||
NEXT_SYMBOL = *str;
|
enum CORE_STATE state = CORE_START;
|
||||||
if (NEXT_SYMBOL==',') /* end of this input */ {
|
for (; *str && state != CORE_INVALID; str++)
|
||||||
str++;
|
{
|
||||||
break;
|
NEXT_SYMBOL = *str;
|
||||||
}
|
if (NEXT_SYMBOL == ',') /* end of this input */
|
||||||
switch(state) {
|
{
|
||||||
case CORE_START:
|
str++;
|
||||||
if(ee_isdigit(NEXT_SYMBOL)) {
|
break;
|
||||||
state = CORE_INT;
|
}
|
||||||
}
|
switch (state)
|
||||||
else if( NEXT_SYMBOL == '+' || NEXT_SYMBOL == '-' ) {
|
{
|
||||||
state = CORE_S1;
|
case CORE_START:
|
||||||
}
|
if (ee_isdigit(NEXT_SYMBOL))
|
||||||
else if( NEXT_SYMBOL == '.' ) {
|
{
|
||||||
state = CORE_FLOAT;
|
state = CORE_INT;
|
||||||
}
|
}
|
||||||
else {
|
else if (NEXT_SYMBOL == '+' || NEXT_SYMBOL == '-')
|
||||||
state = CORE_INVALID;
|
{
|
||||||
transition_count[CORE_INVALID]++;
|
state = CORE_S1;
|
||||||
}
|
}
|
||||||
transition_count[CORE_START]++;
|
else if (NEXT_SYMBOL == '.')
|
||||||
break;
|
{
|
||||||
case CORE_S1:
|
state = CORE_FLOAT;
|
||||||
if(ee_isdigit(NEXT_SYMBOL)) {
|
}
|
||||||
state = CORE_INT;
|
else
|
||||||
transition_count[CORE_S1]++;
|
{
|
||||||
}
|
state = CORE_INVALID;
|
||||||
else if( NEXT_SYMBOL == '.' ) {
|
transition_count[CORE_INVALID]++;
|
||||||
state = CORE_FLOAT;
|
}
|
||||||
transition_count[CORE_S1]++;
|
transition_count[CORE_START]++;
|
||||||
}
|
break;
|
||||||
else {
|
case CORE_S1:
|
||||||
state = CORE_INVALID;
|
if (ee_isdigit(NEXT_SYMBOL))
|
||||||
transition_count[CORE_S1]++;
|
{
|
||||||
}
|
state = CORE_INT;
|
||||||
break;
|
transition_count[CORE_S1]++;
|
||||||
case CORE_INT:
|
}
|
||||||
if( NEXT_SYMBOL == '.' ) {
|
else if (NEXT_SYMBOL == '.')
|
||||||
state = CORE_FLOAT;
|
{
|
||||||
transition_count[CORE_INT]++;
|
state = CORE_FLOAT;
|
||||||
}
|
transition_count[CORE_S1]++;
|
||||||
else if(!ee_isdigit(NEXT_SYMBOL)) {
|
}
|
||||||
state = CORE_INVALID;
|
else
|
||||||
transition_count[CORE_INT]++;
|
{
|
||||||
}
|
state = CORE_INVALID;
|
||||||
break;
|
transition_count[CORE_S1]++;
|
||||||
case CORE_FLOAT:
|
}
|
||||||
if( NEXT_SYMBOL == 'E' || NEXT_SYMBOL == 'e' ) {
|
break;
|
||||||
state = CORE_S2;
|
case CORE_INT:
|
||||||
transition_count[CORE_FLOAT]++;
|
if (NEXT_SYMBOL == '.')
|
||||||
}
|
{
|
||||||
else if(!ee_isdigit(NEXT_SYMBOL)) {
|
state = CORE_FLOAT;
|
||||||
state = CORE_INVALID;
|
transition_count[CORE_INT]++;
|
||||||
transition_count[CORE_FLOAT]++;
|
}
|
||||||
}
|
else if (!ee_isdigit(NEXT_SYMBOL))
|
||||||
break;
|
{
|
||||||
case CORE_S2:
|
state = CORE_INVALID;
|
||||||
if( NEXT_SYMBOL == '+' || NEXT_SYMBOL == '-' ) {
|
transition_count[CORE_INT]++;
|
||||||
state = CORE_EXPONENT;
|
}
|
||||||
transition_count[CORE_S2]++;
|
break;
|
||||||
}
|
case CORE_FLOAT:
|
||||||
else {
|
if (NEXT_SYMBOL == 'E' || NEXT_SYMBOL == 'e')
|
||||||
state = CORE_INVALID;
|
{
|
||||||
transition_count[CORE_S2]++;
|
state = CORE_S2;
|
||||||
}
|
transition_count[CORE_FLOAT]++;
|
||||||
break;
|
}
|
||||||
case CORE_EXPONENT:
|
else if (!ee_isdigit(NEXT_SYMBOL))
|
||||||
if(ee_isdigit(NEXT_SYMBOL)) {
|
{
|
||||||
state = CORE_SCIENTIFIC;
|
state = CORE_INVALID;
|
||||||
transition_count[CORE_EXPONENT]++;
|
transition_count[CORE_FLOAT]++;
|
||||||
}
|
}
|
||||||
else {
|
break;
|
||||||
state = CORE_INVALID;
|
case CORE_S2:
|
||||||
transition_count[CORE_EXPONENT]++;
|
if (NEXT_SYMBOL == '+' || NEXT_SYMBOL == '-')
|
||||||
}
|
{
|
||||||
break;
|
state = CORE_EXPONENT;
|
||||||
case CORE_SCIENTIFIC:
|
transition_count[CORE_S2]++;
|
||||||
if(!ee_isdigit(NEXT_SYMBOL)) {
|
}
|
||||||
state = CORE_INVALID;
|
else
|
||||||
transition_count[CORE_INVALID]++;
|
{
|
||||||
}
|
state = CORE_INVALID;
|
||||||
break;
|
transition_count[CORE_S2]++;
|
||||||
default:
|
}
|
||||||
break;
|
break;
|
||||||
}
|
case CORE_EXPONENT:
|
||||||
}
|
if (ee_isdigit(NEXT_SYMBOL))
|
||||||
*instr=str;
|
{
|
||||||
return state;
|
state = CORE_SCIENTIFIC;
|
||||||
|
transition_count[CORE_EXPONENT]++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
state = CORE_INVALID;
|
||||||
|
transition_count[CORE_EXPONENT]++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CORE_SCIENTIFIC:
|
||||||
|
if (!ee_isdigit(NEXT_SYMBOL))
|
||||||
|
{
|
||||||
|
state = CORE_INVALID;
|
||||||
|
transition_count[CORE_INVALID]++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*instr = str;
|
||||||
|
return state;
|
||||||
}
|
}
|
||||||
|
@ -18,193 +18,232 @@ Original Author: Shay Gal-on
|
|||||||
|
|
||||||
#include "coremark.h"
|
#include "coremark.h"
|
||||||
/* Function: get_seed
|
/* Function: get_seed
|
||||||
Get a values that cannot be determined at compile time.
|
Get a values that cannot be determined at compile time.
|
||||||
|
|
||||||
Since different embedded systems and compilers are used, 3 different methods are provided:
|
Since different embedded systems and compilers are used, 3 different
|
||||||
1 - Using a volatile variable. This method is only valid if the compiler is forced to generate code that
|
methods are provided: 1 - Using a volatile variable. This method is only
|
||||||
reads the value of a volatile variable from memory at run time.
|
valid if the compiler is forced to generate code that reads the value of a
|
||||||
Please note, if using this method, you would need to modify core_portme.c to generate training profile.
|
volatile variable from memory at run time. Please note, if using this method,
|
||||||
2 - Command line arguments. This is the preferred method if command line arguments are supported.
|
you would need to modify core_portme.c to generate training profile. 2 -
|
||||||
3 - System function. If none of the first 2 methods is available on the platform,
|
Command line arguments. This is the preferred method if command line
|
||||||
a system function which is not a stub can be used.
|
arguments are supported. 3 - System function. If none of the first 2 methods
|
||||||
|
is available on the platform, a system function which is not a stub can be
|
||||||
e.g. read the value on GPIO pins connected to switches, or invoke special simulator functions.
|
used.
|
||||||
|
|
||||||
|
e.g. read the value on GPIO pins connected to switches, or invoke
|
||||||
|
special simulator functions.
|
||||||
*/
|
*/
|
||||||
#if (SEED_METHOD==SEED_VOLATILE)
|
#if (SEED_METHOD == SEED_VOLATILE)
|
||||||
extern volatile ee_s32 seed1_volatile;
|
extern volatile ee_s32 seed1_volatile;
|
||||||
extern volatile ee_s32 seed2_volatile;
|
extern volatile ee_s32 seed2_volatile;
|
||||||
extern volatile ee_s32 seed3_volatile;
|
extern volatile ee_s32 seed3_volatile;
|
||||||
extern volatile ee_s32 seed4_volatile;
|
extern volatile ee_s32 seed4_volatile;
|
||||||
extern volatile ee_s32 seed5_volatile;
|
extern volatile ee_s32 seed5_volatile;
|
||||||
ee_s32 get_seed_32(int i) {
|
ee_s32
|
||||||
ee_s32 retval;
|
get_seed_32(int i)
|
||||||
switch (i) {
|
{
|
||||||
case 1:
|
ee_s32 retval;
|
||||||
retval=seed1_volatile;
|
switch (i)
|
||||||
break;
|
{
|
||||||
case 2:
|
case 1:
|
||||||
retval=seed2_volatile;
|
retval = seed1_volatile;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 2:
|
||||||
retval=seed3_volatile;
|
retval = seed2_volatile;
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 3:
|
||||||
retval=seed4_volatile;
|
retval = seed3_volatile;
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 4:
|
||||||
retval=seed5_volatile;
|
retval = seed4_volatile;
|
||||||
break;
|
break;
|
||||||
default:
|
case 5:
|
||||||
retval=0;
|
retval = seed5_volatile;
|
||||||
break;
|
break;
|
||||||
}
|
default:
|
||||||
return retval;
|
retval = 0;
|
||||||
}
|
break;
|
||||||
#elif (SEED_METHOD==SEED_ARG)
|
}
|
||||||
ee_s32 parseval(char *valstring) {
|
return retval;
|
||||||
ee_s32 retval=0;
|
}
|
||||||
ee_s32 neg=1;
|
#elif (SEED_METHOD == SEED_ARG)
|
||||||
int hexmode=0;
|
ee_s32
|
||||||
if (*valstring == '-') {
|
parseval(char *valstring)
|
||||||
neg=-1;
|
{
|
||||||
valstring++;
|
ee_s32 retval = 0;
|
||||||
}
|
ee_s32 neg = 1;
|
||||||
if ((valstring[0] == '0') && (valstring[1] == 'x')) {
|
int hexmode = 0;
|
||||||
hexmode=1;
|
if (*valstring == '-')
|
||||||
valstring+=2;
|
{
|
||||||
}
|
neg = -1;
|
||||||
/* first look for digits */
|
valstring++;
|
||||||
if (hexmode) {
|
}
|
||||||
while (((*valstring >= '0') && (*valstring <= '9')) || ((*valstring >= 'a') && (*valstring <= 'f'))) {
|
if ((valstring[0] == '0') && (valstring[1] == 'x'))
|
||||||
ee_s32 digit=*valstring-'0';
|
{
|
||||||
if (digit>9)
|
hexmode = 1;
|
||||||
digit=10+*valstring-'a';
|
valstring += 2;
|
||||||
retval*=16;
|
}
|
||||||
retval+=digit;
|
/* first look for digits */
|
||||||
valstring++;
|
if (hexmode)
|
||||||
}
|
{
|
||||||
} else {
|
while (((*valstring >= '0') && (*valstring <= '9'))
|
||||||
while ((*valstring >= '0') && (*valstring <= '9')) {
|
|| ((*valstring >= 'a') && (*valstring <= 'f')))
|
||||||
ee_s32 digit=*valstring-'0';
|
{
|
||||||
retval*=10;
|
ee_s32 digit = *valstring - '0';
|
||||||
retval+=digit;
|
if (digit > 9)
|
||||||
valstring++;
|
digit = 10 + *valstring - 'a';
|
||||||
}
|
retval *= 16;
|
||||||
}
|
retval += digit;
|
||||||
/* now add qualifiers */
|
valstring++;
|
||||||
if (*valstring=='K')
|
}
|
||||||
retval*=1024;
|
}
|
||||||
if (*valstring=='M')
|
else
|
||||||
retval*=1024*1024;
|
{
|
||||||
|
while ((*valstring >= '0') && (*valstring <= '9'))
|
||||||
|
{
|
||||||
|
ee_s32 digit = *valstring - '0';
|
||||||
|
retval *= 10;
|
||||||
|
retval += digit;
|
||||||
|
valstring++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* now add qualifiers */
|
||||||
|
if (*valstring == 'K')
|
||||||
|
retval *= 1024;
|
||||||
|
if (*valstring == 'M')
|
||||||
|
retval *= 1024 * 1024;
|
||||||
|
|
||||||
retval*=neg;
|
retval *= neg;
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
ee_s32 get_seed_args(int i, int argc, char *argv[]) {
|
ee_s32
|
||||||
if (argc>i)
|
get_seed_args(int i, int argc, char *argv[])
|
||||||
return parseval(argv[i]);
|
{
|
||||||
return 0;
|
if (argc > i)
|
||||||
|
return parseval(argv[i]);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif (SEED_METHOD==SEED_FUNC)
|
#elif (SEED_METHOD == SEED_FUNC)
|
||||||
/* If using OS based function, you must define and implement the functions below in core_portme.h and core_portme.c ! */
|
/* If using OS based function, you must define and implement the functions below
|
||||||
ee_s32 get_seed_32(int i) {
|
* in core_portme.h and core_portme.c ! */
|
||||||
ee_s32 retval;
|
ee_s32
|
||||||
switch (i) {
|
get_seed_32(int i)
|
||||||
case 1:
|
{
|
||||||
retval=portme_sys1();
|
ee_s32 retval;
|
||||||
break;
|
switch (i)
|
||||||
case 2:
|
{
|
||||||
retval=portme_sys2();
|
case 1:
|
||||||
break;
|
retval = portme_sys1();
|
||||||
case 3:
|
break;
|
||||||
retval=portme_sys3();
|
case 2:
|
||||||
break;
|
retval = portme_sys2();
|
||||||
case 4:
|
break;
|
||||||
retval=portme_sys4();
|
case 3:
|
||||||
break;
|
retval = portme_sys3();
|
||||||
case 5:
|
break;
|
||||||
retval=portme_sys5();
|
case 4:
|
||||||
break;
|
retval = portme_sys4();
|
||||||
default:
|
break;
|
||||||
retval=0;
|
case 5:
|
||||||
break;
|
retval = portme_sys5();
|
||||||
}
|
break;
|
||||||
return retval;
|
default:
|
||||||
|
retval = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Function: crc*
|
/* Function: crc*
|
||||||
Service functions to calculate 16b CRC code.
|
Service functions to calculate 16b CRC code.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
ee_u16 crcu8(ee_u8 data, ee_u16 crc )
|
ee_u16
|
||||||
|
crcu8(ee_u8 data, ee_u16 crc)
|
||||||
{
|
{
|
||||||
ee_u8 i=0,x16=0,carry=0;
|
ee_u8 i = 0, x16 = 0, carry = 0;
|
||||||
|
|
||||||
for (i = 0; i < 8; i++)
|
for (i = 0; i < 8; i++)
|
||||||
{
|
{
|
||||||
x16 = (ee_u8)((data & 1) ^ ((ee_u8)crc & 1));
|
x16 = (ee_u8)((data & 1) ^ ((ee_u8)crc & 1));
|
||||||
data >>= 1;
|
data >>= 1;
|
||||||
|
|
||||||
if (x16 == 1)
|
if (x16 == 1)
|
||||||
{
|
{
|
||||||
crc ^= 0x4002;
|
crc ^= 0x4002;
|
||||||
carry = 1;
|
carry = 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
carry = 0;
|
carry = 0;
|
||||||
crc >>= 1;
|
crc >>= 1;
|
||||||
if (carry)
|
if (carry)
|
||||||
crc |= 0x8000;
|
crc |= 0x8000;
|
||||||
else
|
else
|
||||||
crc &= 0x7fff;
|
crc &= 0x7fff;
|
||||||
}
|
}
|
||||||
return crc;
|
return crc;
|
||||||
}
|
|
||||||
ee_u16 crcu16(ee_u16 newval, ee_u16 crc) {
|
|
||||||
crc=crcu8( (ee_u8) (newval) ,crc);
|
|
||||||
crc=crcu8( (ee_u8) ((newval)>>8) ,crc);
|
|
||||||
return crc;
|
|
||||||
}
|
}
|
||||||
ee_u16 crcu32(ee_u32 newval, ee_u16 crc) {
|
ee_u16
|
||||||
crc=crc16((ee_s16) newval ,crc);
|
crcu16(ee_u16 newval, ee_u16 crc)
|
||||||
crc=crc16((ee_s16) (newval>>16) ,crc);
|
{
|
||||||
return crc;
|
crc = crcu8((ee_u8)(newval), crc);
|
||||||
|
crc = crcu8((ee_u8)((newval) >> 8), crc);
|
||||||
|
return crc;
|
||||||
}
|
}
|
||||||
ee_u16 crc16(ee_s16 newval, ee_u16 crc) {
|
ee_u16
|
||||||
return crcu16((ee_u16)newval, crc);
|
crcu32(ee_u32 newval, ee_u16 crc)
|
||||||
|
{
|
||||||
|
crc = crc16((ee_s16)newval, crc);
|
||||||
|
crc = crc16((ee_s16)(newval >> 16), crc);
|
||||||
|
return crc;
|
||||||
|
}
|
||||||
|
ee_u16
|
||||||
|
crc16(ee_s16 newval, ee_u16 crc)
|
||||||
|
{
|
||||||
|
return crcu16((ee_u16)newval, crc);
|
||||||
}
|
}
|
||||||
|
|
||||||
ee_u8 check_data_types() {
|
ee_u8
|
||||||
ee_u8 retval=0;
|
check_data_types()
|
||||||
if (sizeof(ee_u8) != 1) {
|
{
|
||||||
ee_printf("ERROR: ee_u8 is not an 8b datatype!\n");
|
ee_u8 retval = 0;
|
||||||
retval++;
|
if (sizeof(ee_u8) != 1)
|
||||||
}
|
{
|
||||||
if (sizeof(ee_u16) != 2) {
|
ee_printf("ERROR: ee_u8 is not an 8b datatype!\n");
|
||||||
ee_printf("ERROR: ee_u16 is not a 16b datatype!\n");
|
retval++;
|
||||||
retval++;
|
}
|
||||||
}
|
if (sizeof(ee_u16) != 2)
|
||||||
if (sizeof(ee_s16) != 2) {
|
{
|
||||||
ee_printf("ERROR: ee_s16 is not a 16b datatype!\n");
|
ee_printf("ERROR: ee_u16 is not a 16b datatype!\n");
|
||||||
retval++;
|
retval++;
|
||||||
}
|
}
|
||||||
if (sizeof(ee_s32) != 4) {
|
if (sizeof(ee_s16) != 2)
|
||||||
ee_printf("ERROR: ee_s32 is not a 32b datatype!\n");
|
{
|
||||||
retval++;
|
ee_printf("ERROR: ee_s16 is not a 16b datatype!\n");
|
||||||
}
|
retval++;
|
||||||
if (sizeof(ee_u32) != 4) {
|
}
|
||||||
ee_printf("ERROR: ee_u32 is not a 32b datatype!\n");
|
if (sizeof(ee_s32) != 4)
|
||||||
retval++;
|
{
|
||||||
}
|
ee_printf("ERROR: ee_s32 is not a 32b datatype!\n");
|
||||||
if (sizeof(ee_ptr_int) != sizeof(int *)) {
|
retval++;
|
||||||
ee_printf("ERROR: ee_ptr_int is not a datatype that holds an int pointer!\n");
|
}
|
||||||
retval++;
|
if (sizeof(ee_u32) != 4)
|
||||||
}
|
{
|
||||||
if (retval>0) {
|
ee_printf("ERROR: ee_u32 is not a 32b datatype!\n");
|
||||||
ee_printf("ERROR: Please modify the datatypes in core_portme.h!\n");
|
retval++;
|
||||||
}
|
}
|
||||||
return retval;
|
if (sizeof(ee_ptr_int) != sizeof(int *))
|
||||||
|
{
|
||||||
|
ee_printf(
|
||||||
|
"ERROR: ee_ptr_int is not a datatype that holds an int pointer!\n");
|
||||||
|
retval++;
|
||||||
|
}
|
||||||
|
if (retval > 0)
|
||||||
|
{
|
||||||
|
ee_printf("ERROR: Please modify the datatypes in core_portme.h!\n");
|
||||||
|
}
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
@ -17,23 +17,23 @@ Original Author: Shay Gal-on
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* Topic: Description
|
/* Topic: Description
|
||||||
This file contains declarations of the various benchmark functions.
|
This file contains declarations of the various benchmark functions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Configuration: TOTAL_DATA_SIZE
|
/* Configuration: TOTAL_DATA_SIZE
|
||||||
Define total size for data algorithms will operate on
|
Define total size for data algorithms will operate on
|
||||||
*/
|
*/
|
||||||
#ifndef TOTAL_DATA_SIZE
|
#ifndef TOTAL_DATA_SIZE
|
||||||
#define TOTAL_DATA_SIZE 2*1000
|
#define TOTAL_DATA_SIZE 2 * 1000
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define SEED_ARG 0
|
#define SEED_ARG 0
|
||||||
#define SEED_FUNC 1
|
#define SEED_FUNC 1
|
||||||
#define SEED_VOLATILE 2
|
#define SEED_VOLATILE 2
|
||||||
|
|
||||||
#define MEM_STATIC 0
|
#define MEM_STATIC 0
|
||||||
#define MEM_MALLOC 1
|
#define MEM_MALLOC 1
|
||||||
#define MEM_STACK 2
|
#define MEM_STACK 2
|
||||||
|
|
||||||
#include "core_portme.h"
|
#include "core_portme.h"
|
||||||
|
|
||||||
@ -48,8 +48,8 @@ Original Author: Shay Gal-on
|
|||||||
void *iterate(void *pres);
|
void *iterate(void *pres);
|
||||||
|
|
||||||
/* Typedef: secs_ret
|
/* Typedef: secs_ret
|
||||||
For machines that have floating point support, get number of seconds as a double.
|
For machines that have floating point support, get number of seconds as
|
||||||
Otherwise an unsigned int.
|
a double. Otherwise an unsigned int.
|
||||||
*/
|
*/
|
||||||
#if HAS_FLOAT
|
#if HAS_FLOAT
|
||||||
typedef double secs_ret;
|
typedef double secs_ret;
|
||||||
@ -58,47 +58,48 @@ typedef ee_u32 secs_ret;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if MAIN_HAS_NORETURN
|
#if MAIN_HAS_NORETURN
|
||||||
#define MAIN_RETURN_VAL
|
#define MAIN_RETURN_VAL
|
||||||
#define MAIN_RETURN_TYPE void
|
#define MAIN_RETURN_TYPE void
|
||||||
#else
|
#else
|
||||||
#define MAIN_RETURN_VAL 0
|
#define MAIN_RETURN_VAL 0
|
||||||
#define MAIN_RETURN_TYPE int
|
#define MAIN_RETURN_TYPE int
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void start_time(void);
|
void start_time(void);
|
||||||
void stop_time(void);
|
void stop_time(void);
|
||||||
CORE_TICKS get_time(void);
|
CORE_TICKS get_time(void);
|
||||||
secs_ret time_in_secs(CORE_TICKS ticks);
|
secs_ret time_in_secs(CORE_TICKS ticks);
|
||||||
|
|
||||||
/* Misc useful functions */
|
/* Misc useful functions */
|
||||||
ee_u16 crcu8(ee_u8 data, ee_u16 crc);
|
ee_u16 crcu8(ee_u8 data, ee_u16 crc);
|
||||||
ee_u16 crc16(ee_s16 newval, ee_u16 crc);
|
ee_u16 crc16(ee_s16 newval, ee_u16 crc);
|
||||||
ee_u16 crcu16(ee_u16 newval, ee_u16 crc);
|
ee_u16 crcu16(ee_u16 newval, ee_u16 crc);
|
||||||
ee_u16 crcu32(ee_u32 newval, ee_u16 crc);
|
ee_u16 crcu32(ee_u32 newval, ee_u16 crc);
|
||||||
ee_u8 check_data_types();
|
ee_u8 check_data_types(void);
|
||||||
void *portable_malloc(ee_size_t size);
|
void * portable_malloc(ee_size_t size);
|
||||||
void portable_free(void *p);
|
void portable_free(void *p);
|
||||||
ee_s32 parseval(char *valstring);
|
ee_s32 parseval(char *valstring);
|
||||||
|
|
||||||
/* Algorithm IDS */
|
/* Algorithm IDS */
|
||||||
#define ID_LIST (1<<0)
|
#define ID_LIST (1 << 0)
|
||||||
#define ID_MATRIX (1<<1)
|
#define ID_MATRIX (1 << 1)
|
||||||
#define ID_STATE (1<<2)
|
#define ID_STATE (1 << 2)
|
||||||
#define ALL_ALGORITHMS_MASK (ID_LIST|ID_MATRIX|ID_STATE)
|
#define ALL_ALGORITHMS_MASK (ID_LIST | ID_MATRIX | ID_STATE)
|
||||||
#define NUM_ALGORITHMS 3
|
#define NUM_ALGORITHMS 3
|
||||||
|
|
||||||
/* list data structures */
|
/* list data structures */
|
||||||
typedef struct list_data_s {
|
typedef struct list_data_s
|
||||||
ee_s16 data16;
|
{
|
||||||
ee_s16 idx;
|
ee_s16 data16;
|
||||||
|
ee_s16 idx;
|
||||||
} list_data;
|
} list_data;
|
||||||
|
|
||||||
typedef struct list_head_s {
|
typedef struct list_head_s
|
||||||
struct list_head_s *next;
|
{
|
||||||
struct list_data_s *info;
|
struct list_head_s *next;
|
||||||
|
struct list_data_s *info;
|
||||||
} list_head;
|
} list_head;
|
||||||
|
|
||||||
|
|
||||||
/*matrix benchmark related stuff */
|
/*matrix benchmark related stuff */
|
||||||
#define MATDAT_INT 1
|
#define MATDAT_INT 1
|
||||||
#if MATDAT_INT
|
#if MATDAT_INT
|
||||||
@ -109,66 +110,74 @@ typedef ee_f16 MATDAT;
|
|||||||
typedef ee_f32 MATRES;
|
typedef ee_f32 MATRES;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct MAT_PARAMS_S {
|
typedef struct MAT_PARAMS_S
|
||||||
int N;
|
{
|
||||||
MATDAT *A;
|
int N;
|
||||||
MATDAT *B;
|
MATDAT *A;
|
||||||
MATRES *C;
|
MATDAT *B;
|
||||||
|
MATRES *C;
|
||||||
} mat_params;
|
} mat_params;
|
||||||
|
|
||||||
/* state machine related stuff */
|
/* state machine related stuff */
|
||||||
/* List of all the possible states for the FSM */
|
/* List of all the possible states for the FSM */
|
||||||
typedef enum CORE_STATE {
|
typedef enum CORE_STATE
|
||||||
CORE_START=0,
|
{
|
||||||
CORE_INVALID,
|
CORE_START = 0,
|
||||||
CORE_S1,
|
CORE_INVALID,
|
||||||
CORE_S2,
|
CORE_S1,
|
||||||
CORE_INT,
|
CORE_S2,
|
||||||
CORE_FLOAT,
|
CORE_INT,
|
||||||
CORE_EXPONENT,
|
CORE_FLOAT,
|
||||||
CORE_SCIENTIFIC,
|
CORE_EXPONENT,
|
||||||
NUM_CORE_STATES
|
CORE_SCIENTIFIC,
|
||||||
} core_state_e ;
|
NUM_CORE_STATES
|
||||||
|
} core_state_e;
|
||||||
|
|
||||||
|
|
||||||
/* Helper structure to hold results */
|
/* Helper structure to hold results */
|
||||||
typedef struct RESULTS_S {
|
typedef struct RESULTS_S
|
||||||
/* inputs */
|
{
|
||||||
ee_s16 seed1; /* Initializing seed */
|
/* inputs */
|
||||||
ee_s16 seed2; /* Initializing seed */
|
ee_s16 seed1; /* Initializing seed */
|
||||||
ee_s16 seed3; /* Initializing seed */
|
ee_s16 seed2; /* Initializing seed */
|
||||||
void *memblock[4]; /* Pointer to safe memory location */
|
ee_s16 seed3; /* Initializing seed */
|
||||||
ee_u32 size; /* Size of the data */
|
void * memblock[4]; /* Pointer to safe memory location */
|
||||||
ee_u32 iterations; /* Number of iterations to execute */
|
ee_u32 size; /* Size of the data */
|
||||||
ee_u32 execs; /* Bitmask of operations to execute */
|
ee_u32 iterations; /* Number of iterations to execute */
|
||||||
struct list_head_s *list;
|
ee_u32 execs; /* Bitmask of operations to execute */
|
||||||
mat_params mat;
|
struct list_head_s *list;
|
||||||
/* outputs */
|
mat_params mat;
|
||||||
ee_u16 crc;
|
/* outputs */
|
||||||
ee_u16 crclist;
|
ee_u16 crc;
|
||||||
ee_u16 crcmatrix;
|
ee_u16 crclist;
|
||||||
ee_u16 crcstate;
|
ee_u16 crcmatrix;
|
||||||
ee_s16 err;
|
ee_u16 crcstate;
|
||||||
/* ultithread specific */
|
ee_s16 err;
|
||||||
core_portable port;
|
/* ultithread specific */
|
||||||
|
core_portable port;
|
||||||
} core_results;
|
} core_results;
|
||||||
|
|
||||||
/* Multicore execution handling */
|
/* Multicore execution handling */
|
||||||
#if (MULTITHREAD>1)
|
#if (MULTITHREAD > 1)
|
||||||
ee_u8 core_start_parallel(core_results *res);
|
ee_u8 core_start_parallel(core_results *res);
|
||||||
ee_u8 core_stop_parallel(core_results *res);
|
ee_u8 core_stop_parallel(core_results *res);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* list benchmark functions */
|
/* list benchmark functions */
|
||||||
list_head *core_list_init(ee_u32 blksize, list_head *memblock, ee_s16 seed);
|
list_head *core_list_init(ee_u32 blksize, list_head *memblock, ee_s16 seed);
|
||||||
ee_u16 core_bench_list(core_results *res, ee_s16 finder_idx);
|
ee_u16 core_bench_list(core_results *res, ee_s16 finder_idx);
|
||||||
|
|
||||||
/* state benchmark functions */
|
/* state benchmark functions */
|
||||||
void core_init_state(ee_u32 size, ee_s16 seed, ee_u8 *p);
|
void core_init_state(ee_u32 size, ee_s16 seed, ee_u8 *p);
|
||||||
ee_u16 core_bench_state(ee_u32 blksize, ee_u8 *memblock,
|
ee_u16 core_bench_state(ee_u32 blksize,
|
||||||
ee_s16 seed1, ee_s16 seed2, ee_s16 step, ee_u16 crc);
|
ee_u8 *memblock,
|
||||||
|
ee_s16 seed1,
|
||||||
|
ee_s16 seed2,
|
||||||
|
ee_s16 step,
|
||||||
|
ee_u16 crc);
|
||||||
|
|
||||||
/* matrix benchmark functions */
|
/* matrix benchmark functions */
|
||||||
ee_u32 core_init_matrix(ee_u32 blksize, void *memblk, ee_s32 seed, mat_params *p);
|
ee_u32 core_init_matrix(ee_u32 blksize,
|
||||||
|
void * memblk,
|
||||||
|
ee_s32 seed,
|
||||||
|
mat_params *p);
|
||||||
ee_u16 core_bench_matrix(mat_params *p, ee_s16 seed, ee_u16 crc);
|
ee_u16 core_bench_matrix(mat_params *p, ee_s16 seed, ee_u16 crc);
|
||||||
|
|
||||||
|
6
riscv-coremark/coremark/coremark.md5
Normal file
6
riscv-coremark/coremark/coremark.md5
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
8d082dc4a9676c02731a8cf209339072 core_list_join.c
|
||||||
|
c984863b84b59185d8b5fb81c1ca7535 core_main.c
|
||||||
|
5fa21a0f7c3964167c9691db531ca652 core_matrix.c
|
||||||
|
edcfc7a0b146a50028014f06e6826aa3 core_state.c
|
||||||
|
45540ba2145adea1ec7ea2c72a1fbbcb core_util.c
|
||||||
|
8ca974c013b380dc7f0d6d1afb76eb2d coremark.h
|
126
riscv-coremark/coremark/cygwin/core_portme.mak
Executable file → Normal file
126
riscv-coremark/coremark/cygwin/core_portme.mak
Executable file → Normal file
@ -14,128 +14,4 @@
|
|||||||
#
|
#
|
||||||
# Original Author: Shay Gal-on
|
# Original Author: Shay Gal-on
|
||||||
|
|
||||||
#File: core_portme.mak
|
include posix/core_portme.mak
|
||||||
|
|
||||||
# Flag: OUTFLAG
|
|
||||||
# Use this flag to define how to to get an executable (e.g -o)
|
|
||||||
OUTFLAG= -o
|
|
||||||
# Flag: CC
|
|
||||||
# Use this flag to define compiler to use
|
|
||||||
CC = gcc
|
|
||||||
# Flag: CFLAGS
|
|
||||||
# Use this flag to define compiler options. Note, you can add compiler options from the command line using XCFLAGS="other flags"
|
|
||||||
PORT_CFLAGS = -O2
|
|
||||||
FLAGS_STR = "$(PORT_CFLAGS) $(XCFLAGS) $(XLFLAGS) $(LFLAGS_END)"
|
|
||||||
CFLAGS = $(PORT_CFLAGS) -I$(PORT_DIR) -I. -DFLAGS_STR=\"$(FLAGS_STR)\"
|
|
||||||
#Flag: LFLAGS_END
|
|
||||||
# Define any libraries needed for linking or other flags that should come at the end of the link line (e.g. linker scripts).
|
|
||||||
# Note: On certain platforms, the default clock_gettime implementation is supported but requires linking of librt.
|
|
||||||
LFLAGS_END =
|
|
||||||
# Flag: PORT_SRCS
|
|
||||||
# Port specific source files can be added here
|
|
||||||
PORT_SRCS = $(PORT_DIR)/core_portme.c
|
|
||||||
# Flag: LOAD
|
|
||||||
# Define this flag if you need to load to a target, as in a cross compile environment.
|
|
||||||
|
|
||||||
# Flag: RUN
|
|
||||||
# Define this flag if running does not consist of simple invocation of the binary.
|
|
||||||
# In a cross compile environment, you need to define this.
|
|
||||||
|
|
||||||
#For flashing and using a tera term macro, you could use
|
|
||||||
#LOAD = flash ADDR
|
|
||||||
#RUN = ttpmacro coremark.ttl
|
|
||||||
|
|
||||||
#For copying to target and executing via SSH connection, you could use
|
|
||||||
#LOAD = scp $(OUTFILE) user@target:~
|
|
||||||
#RUN = ssh user@target -c
|
|
||||||
|
|
||||||
#For native compilation and execution
|
|
||||||
LOAD = echo Loading done
|
|
||||||
RUN =
|
|
||||||
|
|
||||||
OEXT = .o
|
|
||||||
EXE = .exe
|
|
||||||
|
|
||||||
# Flag: SEPARATE_COMPILE
|
|
||||||
# Define if you need to separate compilation from link stage.
|
|
||||||
# In this case, you also need to define below how to create an object file, and how to link.
|
|
||||||
ifdef SEPARATE_COMPILE
|
|
||||||
|
|
||||||
LD = gcc
|
|
||||||
OBJOUT = -o
|
|
||||||
LFLAGS =
|
|
||||||
OFLAG = -o
|
|
||||||
COUT = -c
|
|
||||||
# Flag: PORT_OBJS
|
|
||||||
# Port specific object files can be added here
|
|
||||||
PORT_OBJS = $(PORT_DIR)/core_portme$(OEXT)
|
|
||||||
PORT_CLEAN = *$(OEXT)
|
|
||||||
|
|
||||||
$(OPATH)%$(OEXT) : %.c
|
|
||||||
$(CC) $(CFLAGS) $(XCFLAGS) $(COUT) $< $(OBJOUT) $@
|
|
||||||
|
|
||||||
endif
|
|
||||||
|
|
||||||
# Target: port_prebuild
|
|
||||||
# Generate any files that are needed before actual build starts.
|
|
||||||
# E.g. generate profile guidance files. Sample PGO generation for gcc enabled with PGO=1
|
|
||||||
# - First, check if PGO was defined on the command line, if so, need to add -fprofile-use to compile line.
|
|
||||||
# - Second, if PGO reference has not yet been generated, add a step to the prebuild that will build a profile-generate version and run it.
|
|
||||||
# Note - Using REBUILD=1
|
|
||||||
#
|
|
||||||
# Use make PGO=1 to invoke this sample processing.
|
|
||||||
|
|
||||||
ifdef PGO
|
|
||||||
ifeq (,$(findstring $(PGO),gen))
|
|
||||||
PGO_STAGE=build_pgo_gcc
|
|
||||||
CFLAGS+=-fprofile-use
|
|
||||||
endif
|
|
||||||
PORT_CLEAN+=*.gcda *.gcno gmon.out
|
|
||||||
endif
|
|
||||||
|
|
||||||
.PHONY: port_prebuild
|
|
||||||
port_prebuild: $(PGO_STAGE)
|
|
||||||
|
|
||||||
.PHONY: build_pgo_gcc
|
|
||||||
build_pgo_gcc:
|
|
||||||
$(MAKE) PGO=gen XCFLAGS="$(XCFLAGS) -fprofile-generate -DTOTAL_DATA_SIZE=1200" ITERATIONS=10 gen_pgo_data REBUILD=1
|
|
||||||
|
|
||||||
# Target: port_postbuild
|
|
||||||
# Generate any files that are needed after actual build end.
|
|
||||||
# E.g. change format to srec, bin, zip in order to be able to load into flash
|
|
||||||
.PHONY: port_postbuild
|
|
||||||
port_postbuild:
|
|
||||||
|
|
||||||
# Target: port_postrun
|
|
||||||
# Do platform specific after run stuff.
|
|
||||||
# E.g. reset the board, backup the logfiles etc.
|
|
||||||
.PHONY: port_postrun
|
|
||||||
port_postrun:
|
|
||||||
|
|
||||||
# Target: port_prerun
|
|
||||||
# Do platform specific after run stuff.
|
|
||||||
# E.g. reset the board, backup the logfiles etc.
|
|
||||||
.PHONY: port_prerun
|
|
||||||
port_prerun:
|
|
||||||
|
|
||||||
# Target: port_postload
|
|
||||||
# Do platform specific after load stuff.
|
|
||||||
# E.g. reset the reset power to the flash eraser
|
|
||||||
.PHONY: port_postload
|
|
||||||
port_postload:
|
|
||||||
|
|
||||||
# Target: port_preload
|
|
||||||
# Do platform specific before load stuff.
|
|
||||||
# E.g. reset the reset power to the flash eraser
|
|
||||||
.PHONY: port_preload
|
|
||||||
port_preload:
|
|
||||||
|
|
||||||
|
|
||||||
# FLAG: OPATH
|
|
||||||
# Path to the output folder. Default - current folder.
|
|
||||||
OPATH = ./
|
|
||||||
MKDIR = mkdir -p
|
|
||||||
|
|
||||||
# FLAG: PERL
|
|
||||||
# Define perl executable to calculate the geomean if running separate.
|
|
||||||
PERL=perl
|
|
||||||
|
17
riscv-coremark/coremark/freebsd/core_portme.mak
Normal file
17
riscv-coremark/coremark/freebsd/core_portme.mak
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
# Copyright 2018 Embedded Microprocessor Benchmark Consortium (EEMBC)
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
# Original Author: Shay Gal-on
|
||||||
|
|
||||||
|
include posix/core_portme.mak
|
125
riscv-coremark/coremark/linux/core_portme.mak
Executable file → Normal file
125
riscv-coremark/coremark/linux/core_portme.mak
Executable file → Normal file
@ -14,127 +14,4 @@
|
|||||||
#
|
#
|
||||||
# Original Author: Shay Gal-on
|
# Original Author: Shay Gal-on
|
||||||
|
|
||||||
#File: core_portme.mak
|
include posix/core_portme.mak
|
||||||
|
|
||||||
# Flag: OUTFLAG
|
|
||||||
# Use this flag to define how to to get an executable (e.g -o)
|
|
||||||
OUTFLAG= -o
|
|
||||||
# Flag: CC
|
|
||||||
# Use this flag to define compiler to use
|
|
||||||
CC = gcc
|
|
||||||
# Flag: CFLAGS
|
|
||||||
# Use this flag to define compiler options. Note, you can add compiler options from the command line using XCFLAGS="other flags"
|
|
||||||
PORT_CFLAGS = -O2
|
|
||||||
FLAGS_STR = "$(PORT_CFLAGS) $(XCFLAGS) $(XLFLAGS) $(LFLAGS_END)"
|
|
||||||
CFLAGS = $(PORT_CFLAGS) -I$(PORT_DIR) -I. -DFLAGS_STR=\"$(FLAGS_STR)\"
|
|
||||||
#Flag: LFLAGS_END
|
|
||||||
# Define any libraries needed for linking or other flags that should come at the end of the link line (e.g. linker scripts).
|
|
||||||
# Note: On certain platforms, the default clock_gettime implementation is supported but requires linking of librt.
|
|
||||||
LFLAGS_END += -lrt
|
|
||||||
# Flag: PORT_SRCS
|
|
||||||
# Port specific source files can be added here
|
|
||||||
PORT_SRCS = $(PORT_DIR)/core_portme.c
|
|
||||||
# Flag: LOAD
|
|
||||||
# Define this flag if you need to load to a target, as in a cross compile environment.
|
|
||||||
|
|
||||||
# Flag: RUN
|
|
||||||
# Define this flag if running does not consist of simple invocation of the binary.
|
|
||||||
# In a cross compile environment, you need to define this.
|
|
||||||
|
|
||||||
#For flashing and using a tera term macro, you could use
|
|
||||||
#LOAD = flash ADDR
|
|
||||||
#RUN = ttpmacro coremark.ttl
|
|
||||||
|
|
||||||
#For copying to target and executing via SSH connection, you could use
|
|
||||||
#LOAD = scp $(OUTFILE) user@target:~
|
|
||||||
#RUN = ssh user@target -c
|
|
||||||
|
|
||||||
#For native compilation and execution
|
|
||||||
LOAD = echo Loading done
|
|
||||||
RUN =
|
|
||||||
|
|
||||||
OEXT = .o
|
|
||||||
EXE = .exe
|
|
||||||
|
|
||||||
# Flag: SEPARATE_COMPILE
|
|
||||||
# Define if you need to separate compilation from link stage.
|
|
||||||
# In this case, you also need to define below how to create an object file, and how to link.
|
|
||||||
ifdef SEPARATE_COMPILE
|
|
||||||
|
|
||||||
LD = gcc
|
|
||||||
OBJOUT = -o
|
|
||||||
LFLAGS =
|
|
||||||
OFLAG = -o
|
|
||||||
COUT = -c
|
|
||||||
# Flag: PORT_OBJS
|
|
||||||
# Port specific object files can be added here
|
|
||||||
PORT_OBJS = $(PORT_DIR)/core_portme$(OEXT)
|
|
||||||
PORT_CLEAN = *$(OEXT)
|
|
||||||
|
|
||||||
$(OPATH)%$(OEXT) : %.c
|
|
||||||
$(CC) $(CFLAGS) $(XCFLAGS) $(COUT) $< $(OBJOUT) $@
|
|
||||||
|
|
||||||
endif
|
|
||||||
|
|
||||||
# Target: port_prebuild
|
|
||||||
# Generate any files that are needed before actual build starts.
|
|
||||||
# E.g. generate profile guidance files. Sample PGO generation for gcc enabled with PGO=1
|
|
||||||
# - First, check if PGO was defined on the command line, if so, need to add -fprofile-use to compile line.
|
|
||||||
# - Second, if PGO reference has not yet been generated, add a step to the prebuild that will build a profile-generate version and run it.
|
|
||||||
# Note - Using REBUILD=1
|
|
||||||
#
|
|
||||||
# Use make PGO=1 to invoke this sample processing.
|
|
||||||
|
|
||||||
ifdef PGO
|
|
||||||
ifeq (,$(findstring $(PGO),gen))
|
|
||||||
PGO_STAGE=build_pgo_gcc
|
|
||||||
CFLAGS+=-fprofile-use
|
|
||||||
endif
|
|
||||||
PORT_CLEAN+=*.gcda *.gcno gmon.out
|
|
||||||
endif
|
|
||||||
|
|
||||||
.PHONY: port_prebuild
|
|
||||||
port_prebuild: $(PGO_STAGE)
|
|
||||||
|
|
||||||
.PHONY: build_pgo_gcc
|
|
||||||
build_pgo_gcc:
|
|
||||||
$(MAKE) PGO=gen XCFLAGS="$(XCFLAGS) -fprofile-generate -DTOTAL_DATA_SIZE=1200" ITERATIONS=10 gen_pgo_data REBUILD=1
|
|
||||||
|
|
||||||
# Target: port_postbuild
|
|
||||||
# Generate any files that are needed after actual build end.
|
|
||||||
# E.g. change format to srec, bin, zip in order to be able to load into flash
|
|
||||||
.PHONY: port_postbuild
|
|
||||||
port_postbuild:
|
|
||||||
|
|
||||||
# Target: port_postrun
|
|
||||||
# Do platform specific after run stuff.
|
|
||||||
# E.g. reset the board, backup the logfiles etc.
|
|
||||||
.PHONY: port_postrun
|
|
||||||
port_postrun:
|
|
||||||
|
|
||||||
# Target: port_prerun
|
|
||||||
# Do platform specific after run stuff.
|
|
||||||
# E.g. reset the board, backup the logfiles etc.
|
|
||||||
.PHONY: port_prerun
|
|
||||||
port_prerun:
|
|
||||||
|
|
||||||
# Target: port_postload
|
|
||||||
# Do platform specific after load stuff.
|
|
||||||
# E.g. reset the reset power to the flash eraser
|
|
||||||
.PHONY: port_postload
|
|
||||||
port_postload:
|
|
||||||
|
|
||||||
# Target: port_preload
|
|
||||||
# Do platform specific before load stuff.
|
|
||||||
# E.g. reset the reset power to the flash eraser
|
|
||||||
.PHONY: port_preload
|
|
||||||
port_preload:
|
|
||||||
|
|
||||||
# FLAG: OPATH
|
|
||||||
# Path to the output folder. Default - current folder.
|
|
||||||
OPATH = ./
|
|
||||||
MKDIR = mkdir -p
|
|
||||||
|
|
||||||
# FLAG: PERL
|
|
||||||
# Define perl executable to calculate the geomean if running separate.
|
|
||||||
PERL=/usr/bin/perl
|
|
||||||
|
18
riscv-coremark/coremark/macos/core_portme.mak
Normal file
18
riscv-coremark/coremark/macos/core_portme.mak
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Copyright 2018 Embedded Microprocessor Benchmark Consortium (EEMBC)
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
# Original Author: Shay Gal-on
|
||||||
|
|
||||||
|
NO_LIBRT = 1
|
||||||
|
include posix/core_portme.mak
|
419
riscv-coremark/coremark/posix/core_portme.c
Normal file
419
riscv-coremark/coremark/posix/core_portme.c
Normal file
@ -0,0 +1,419 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2018 Embedded Microprocessor Benchmark Consortium (EEMBC)
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
Original Author: Shay Gal-on
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "coremark.h"
|
||||||
|
#if CALLGRIND_RUN
|
||||||
|
#include <valgrind/callgrind.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (MEM_METHOD == MEM_MALLOC)
|
||||||
|
/* Function: portable_malloc
|
||||||
|
Provide malloc() functionality in a platform specific way.
|
||||||
|
*/
|
||||||
|
void *
|
||||||
|
portable_malloc(size_t size)
|
||||||
|
{
|
||||||
|
return malloc(size);
|
||||||
|
}
|
||||||
|
/* Function: portable_free
|
||||||
|
Provide free() functionality in a platform specific way.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
portable_free(void *p)
|
||||||
|
{
|
||||||
|
free(p);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
void *
|
||||||
|
portable_malloc(size_t size)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
void
|
||||||
|
portable_free(void *p)
|
||||||
|
{
|
||||||
|
p = NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (SEED_METHOD == SEED_VOLATILE)
|
||||||
|
#if VALIDATION_RUN
|
||||||
|
volatile ee_s32 seed1_volatile = 0x3415;
|
||||||
|
volatile ee_s32 seed2_volatile = 0x3415;
|
||||||
|
volatile ee_s32 seed3_volatile = 0x66;
|
||||||
|
#endif
|
||||||
|
#if PERFORMANCE_RUN
|
||||||
|
volatile ee_s32 seed1_volatile = 0x0;
|
||||||
|
volatile ee_s32 seed2_volatile = 0x0;
|
||||||
|
volatile ee_s32 seed3_volatile = 0x66;
|
||||||
|
#endif
|
||||||
|
#if PROFILE_RUN
|
||||||
|
volatile ee_s32 seed1_volatile = 0x8;
|
||||||
|
volatile ee_s32 seed2_volatile = 0x8;
|
||||||
|
volatile ee_s32 seed3_volatile = 0x8;
|
||||||
|
#endif
|
||||||
|
volatile ee_s32 seed4_volatile = ITERATIONS;
|
||||||
|
volatile ee_s32 seed5_volatile = 0;
|
||||||
|
#endif
|
||||||
|
/* Porting: Timing functions
|
||||||
|
How to capture time and convert to seconds must be ported to whatever is
|
||||||
|
supported by the platform. e.g. Read value from on board RTC, read value from
|
||||||
|
cpu clock cycles performance counter etc. Sample implementation for standard
|
||||||
|
time.h and windows.h definitions included.
|
||||||
|
*/
|
||||||
|
/* Define: TIMER_RES_DIVIDER
|
||||||
|
Divider to trade off timer resolution and total time that can be
|
||||||
|
measured.
|
||||||
|
|
||||||
|
Use lower values to increase resolution, but make sure that overflow
|
||||||
|
does not occur. If there are issues with the return value overflowing,
|
||||||
|
increase this value.
|
||||||
|
*/
|
||||||
|
#if USE_CLOCK
|
||||||
|
#define NSECS_PER_SEC CLOCKS_PER_SEC
|
||||||
|
#define EE_TIMER_TICKER_RATE 1000
|
||||||
|
#define CORETIMETYPE clock_t
|
||||||
|
#define GETMYTIME(_t) (*_t = clock())
|
||||||
|
#define MYTIMEDIFF(fin, ini) ((fin) - (ini))
|
||||||
|
#define TIMER_RES_DIVIDER 1
|
||||||
|
#define SAMPLE_TIME_IMPLEMENTATION 1
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
#define NSECS_PER_SEC 10000000
|
||||||
|
#define EE_TIMER_TICKER_RATE 1000
|
||||||
|
#define CORETIMETYPE FILETIME
|
||||||
|
#define GETMYTIME(_t) GetSystemTimeAsFileTime(_t)
|
||||||
|
#define MYTIMEDIFF(fin, ini) \
|
||||||
|
(((*(__int64 *)&fin) - (*(__int64 *)&ini)) / TIMER_RES_DIVIDER)
|
||||||
|
/* setting to millisces resolution by default with MSDEV */
|
||||||
|
#ifndef TIMER_RES_DIVIDER
|
||||||
|
#define TIMER_RES_DIVIDER 1000
|
||||||
|
#endif
|
||||||
|
#define SAMPLE_TIME_IMPLEMENTATION 1
|
||||||
|
#elif HAS_TIME_H
|
||||||
|
#define NSECS_PER_SEC 1000000000
|
||||||
|
#define EE_TIMER_TICKER_RATE 1000
|
||||||
|
#define CORETIMETYPE struct timespec
|
||||||
|
#define GETMYTIME(_t) clock_gettime(CLOCK_REALTIME, _t)
|
||||||
|
#define MYTIMEDIFF(fin, ini) \
|
||||||
|
((fin.tv_sec - ini.tv_sec) * (NSECS_PER_SEC / TIMER_RES_DIVIDER) \
|
||||||
|
+ (fin.tv_nsec - ini.tv_nsec) / TIMER_RES_DIVIDER)
|
||||||
|
/* setting to 1/1000 of a second resolution by default with linux */
|
||||||
|
#ifndef TIMER_RES_DIVIDER
|
||||||
|
#define TIMER_RES_DIVIDER 1000000
|
||||||
|
#endif
|
||||||
|
#define SAMPLE_TIME_IMPLEMENTATION 1
|
||||||
|
#else
|
||||||
|
#define SAMPLE_TIME_IMPLEMENTATION 0
|
||||||
|
#endif
|
||||||
|
#define EE_TICKS_PER_SEC (NSECS_PER_SEC / TIMER_RES_DIVIDER)
|
||||||
|
|
||||||
|
#if SAMPLE_TIME_IMPLEMENTATION
|
||||||
|
/** Define Host specific (POSIX), or target specific global time variables. */
|
||||||
|
static CORETIMETYPE start_time_val, stop_time_val;
|
||||||
|
|
||||||
|
/* Function: start_time
|
||||||
|
This function will be called right before starting the timed portion of
|
||||||
|
the benchmark.
|
||||||
|
|
||||||
|
Implementation may be capturing a system timer (as implemented in the
|
||||||
|
example code) or zeroing some system parameters - e.g. setting the cpu clocks
|
||||||
|
cycles to 0.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
start_time(void)
|
||||||
|
{
|
||||||
|
GETMYTIME(&start_time_val);
|
||||||
|
#if CALLGRIND_RUN
|
||||||
|
CALLGRIND_START_INSTRUMENTATION
|
||||||
|
#endif
|
||||||
|
#if MICA
|
||||||
|
asm volatile("int3"); /*1 */
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
/* Function: stop_time
|
||||||
|
This function will be called right after ending the timed portion of the
|
||||||
|
benchmark.
|
||||||
|
|
||||||
|
Implementation may be capturing a system timer (as implemented in the
|
||||||
|
example code) or other system parameters - e.g. reading the current value of
|
||||||
|
cpu cycles counter.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
stop_time(void)
|
||||||
|
{
|
||||||
|
#if CALLGRIND_RUN
|
||||||
|
CALLGRIND_STOP_INSTRUMENTATION
|
||||||
|
#endif
|
||||||
|
#if MICA
|
||||||
|
asm volatile("int3"); /*1 */
|
||||||
|
#endif
|
||||||
|
GETMYTIME(&stop_time_val);
|
||||||
|
}
|
||||||
|
/* Function: get_time
|
||||||
|
Return an abstract "ticks" number that signifies time on the system.
|
||||||
|
|
||||||
|
Actual value returned may be cpu cycles, milliseconds or any other
|
||||||
|
value, as long as it can be converted to seconds by <time_in_secs>. This
|
||||||
|
methodology is taken to accomodate any hardware or simulated platform. The
|
||||||
|
sample implementation returns millisecs by default, and the resolution is
|
||||||
|
controlled by <TIMER_RES_DIVIDER>
|
||||||
|
*/
|
||||||
|
CORE_TICKS
|
||||||
|
get_time(void)
|
||||||
|
{
|
||||||
|
CORE_TICKS elapsed
|
||||||
|
= (CORE_TICKS)(MYTIMEDIFF(stop_time_val, start_time_val));
|
||||||
|
return elapsed;
|
||||||
|
}
|
||||||
|
/* Function: time_in_secs
|
||||||
|
Convert the value returned by get_time to seconds.
|
||||||
|
|
||||||
|
The <secs_ret> type is used to accomodate systems with no support for
|
||||||
|
floating point. Default implementation implemented by the EE_TICKS_PER_SEC
|
||||||
|
macro above.
|
||||||
|
*/
|
||||||
|
secs_ret
|
||||||
|
time_in_secs(CORE_TICKS ticks)
|
||||||
|
{
|
||||||
|
secs_ret retval = ((secs_ret)ticks) / (secs_ret)EE_TICKS_PER_SEC;
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#error "Please implement timing functionality in core_portme.c"
|
||||||
|
#endif /* SAMPLE_TIME_IMPLEMENTATION */
|
||||||
|
|
||||||
|
ee_u32 default_num_contexts = MULTITHREAD;
|
||||||
|
|
||||||
|
/* Function: portable_init
|
||||||
|
Target specific initialization code
|
||||||
|
Test for some common mistakes.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
portable_init(core_portable *p, int *argc, char *argv[])
|
||||||
|
{
|
||||||
|
#if PRINT_ARGS
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < *argc; i++)
|
||||||
|
{
|
||||||
|
ee_printf("Arg[%d]=%s\n", i, argv[i]);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (sizeof(ee_ptr_int) != sizeof(ee_u8 *))
|
||||||
|
{
|
||||||
|
ee_printf(
|
||||||
|
"ERROR! Please define ee_ptr_int to a type that holds a "
|
||||||
|
"pointer!\n");
|
||||||
|
}
|
||||||
|
if (sizeof(ee_u32) != 4)
|
||||||
|
{
|
||||||
|
ee_printf("ERROR! Please define ee_u32 to a 32b unsigned type!\n");
|
||||||
|
}
|
||||||
|
#if (MAIN_HAS_NOARGC && (SEED_METHOD == SEED_ARG))
|
||||||
|
ee_printf(
|
||||||
|
"ERROR! Main has no argc, but SEED_METHOD defined to SEED_ARG!\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (MULTITHREAD > 1) && (SEED_METHOD == SEED_ARG)
|
||||||
|
int nargs = *argc, i;
|
||||||
|
if ((nargs > 1) && (*argv[1] == 'M'))
|
||||||
|
{
|
||||||
|
default_num_contexts = parseval(argv[1] + 1);
|
||||||
|
if (default_num_contexts > MULTITHREAD)
|
||||||
|
default_num_contexts = MULTITHREAD;
|
||||||
|
/* Shift args since first arg is directed to the portable part and not
|
||||||
|
* to coremark main */
|
||||||
|
--nargs;
|
||||||
|
for (i = 1; i < nargs; i++)
|
||||||
|
argv[i] = argv[i + 1];
|
||||||
|
*argc = nargs;
|
||||||
|
}
|
||||||
|
#endif /* sample of potential platform specific init via command line, reset \
|
||||||
|
the number of contexts being used if first argument is M<n>*/
|
||||||
|
p->portable_id = 1;
|
||||||
|
}
|
||||||
|
/* Function: portable_fini
|
||||||
|
Target specific final code
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
portable_fini(core_portable *p)
|
||||||
|
{
|
||||||
|
p->portable_id = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if (MULTITHREAD > 1)
|
||||||
|
|
||||||
|
/* Function: core_start_parallel
|
||||||
|
Start benchmarking in a parallel context.
|
||||||
|
|
||||||
|
Three implementations are provided, one using pthreads, one using fork
|
||||||
|
and shared mem, and one using fork and sockets. Other implementations using
|
||||||
|
MCAPI or other standards can easily be devised.
|
||||||
|
*/
|
||||||
|
/* Function: core_stop_parallel
|
||||||
|
Stop a parallel context execution of coremark, and gather the results.
|
||||||
|
|
||||||
|
Three implementations are provided, one using pthreads, one using fork
|
||||||
|
and shared mem, and one using fork and sockets. Other implementations using
|
||||||
|
MCAPI or other standards can easily be devised.
|
||||||
|
*/
|
||||||
|
#if USE_PTHREAD
|
||||||
|
ee_u8
|
||||||
|
core_start_parallel(core_results *res)
|
||||||
|
{
|
||||||
|
return (ee_u8)pthread_create(
|
||||||
|
&(res->port.thread), NULL, iterate, (void *)res);
|
||||||
|
}
|
||||||
|
ee_u8
|
||||||
|
core_stop_parallel(core_results *res)
|
||||||
|
{
|
||||||
|
void *retval;
|
||||||
|
return (ee_u8)pthread_join(res->port.thread, &retval);
|
||||||
|
}
|
||||||
|
#elif USE_FORK
|
||||||
|
static int key_id = 0;
|
||||||
|
ee_u8
|
||||||
|
core_start_parallel(core_results *res)
|
||||||
|
{
|
||||||
|
key_t key = 4321 + key_id;
|
||||||
|
key_id++;
|
||||||
|
res->port.pid = fork();
|
||||||
|
res->port.shmid = shmget(key, 8, IPC_CREAT | 0666);
|
||||||
|
if (res->port.shmid < 0)
|
||||||
|
{
|
||||||
|
ee_printf("ERROR in shmget!\n");
|
||||||
|
}
|
||||||
|
if (res->port.pid == 0)
|
||||||
|
{
|
||||||
|
iterate(res);
|
||||||
|
res->port.shm = shmat(res->port.shmid, NULL, 0);
|
||||||
|
/* copy the validation values to the shared memory area and quit*/
|
||||||
|
if (res->port.shm == (char *)-1)
|
||||||
|
{
|
||||||
|
ee_printf("ERROR in child shmat!\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memcpy(res->port.shm, &(res->crc), 8);
|
||||||
|
shmdt(res->port.shm);
|
||||||
|
}
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
ee_u8
|
||||||
|
core_stop_parallel(core_results *res)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
pid_t wpid = waitpid(res->port.pid, &status, WUNTRACED);
|
||||||
|
if (wpid != res->port.pid)
|
||||||
|
{
|
||||||
|
ee_printf("ERROR waiting for child.\n");
|
||||||
|
if (errno == ECHILD)
|
||||||
|
ee_printf("errno=No such child %d\n", res->port.pid);
|
||||||
|
if (errno == EINTR)
|
||||||
|
ee_printf("errno=Interrupted\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* after process is done, get the values from the shared memory area */
|
||||||
|
res->port.shm = shmat(res->port.shmid, NULL, 0);
|
||||||
|
if (res->port.shm == (char *)-1)
|
||||||
|
{
|
||||||
|
ee_printf("ERROR in parent shmat!\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
memcpy(&(res->crc), res->port.shm, 8);
|
||||||
|
shmdt(res->port.shm);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#elif USE_SOCKET
|
||||||
|
static int key_id = 0;
|
||||||
|
ee_u8
|
||||||
|
core_start_parallel(core_results *res)
|
||||||
|
{
|
||||||
|
int bound, buffer_length = 8;
|
||||||
|
res->port.sa.sin_family = AF_INET;
|
||||||
|
res->port.sa.sin_addr.s_addr = htonl(0x7F000001);
|
||||||
|
res->port.sa.sin_port = htons(7654 + key_id);
|
||||||
|
key_id++;
|
||||||
|
res->port.pid = fork();
|
||||||
|
if (res->port.pid == 0)
|
||||||
|
{ /* benchmark child */
|
||||||
|
iterate(res);
|
||||||
|
res->port.sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||||
|
if (-1 == res->port.sock) /* if socket failed to initialize, exit */
|
||||||
|
{
|
||||||
|
ee_printf("Error Creating Socket");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int bytes_sent = sendto(res->port.sock,
|
||||||
|
&(res->crc),
|
||||||
|
buffer_length,
|
||||||
|
0,
|
||||||
|
(struct sockaddr *)&(res->port.sa),
|
||||||
|
sizeof(struct sockaddr_in));
|
||||||
|
if (bytes_sent < 0)
|
||||||
|
ee_printf("Error sending packet: %s\n", strerror(errno));
|
||||||
|
close(res->port.sock); /* close the socket */
|
||||||
|
}
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
/* parent process, open the socket */
|
||||||
|
res->port.sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||||
|
bound = bind(res->port.sock,
|
||||||
|
(struct sockaddr *)&(res->port.sa),
|
||||||
|
sizeof(struct sockaddr));
|
||||||
|
if (bound < 0)
|
||||||
|
ee_printf("bind(): %s\n", strerror(errno));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
ee_u8
|
||||||
|
core_stop_parallel(core_results *res)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
int fromlen = sizeof(struct sockaddr);
|
||||||
|
int recsize = recvfrom(res->port.sock,
|
||||||
|
&(res->crc),
|
||||||
|
8,
|
||||||
|
0,
|
||||||
|
(struct sockaddr *)&(res->port.sa),
|
||||||
|
&fromlen);
|
||||||
|
if (recsize < 0)
|
||||||
|
{
|
||||||
|
ee_printf("Error in receive: %s\n", strerror(errno));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
pid_t wpid = waitpid(res->port.pid, &status, WUNTRACED);
|
||||||
|
if (wpid != res->port.pid)
|
||||||
|
{
|
||||||
|
ee_printf("ERROR waiting for child.\n");
|
||||||
|
if (errno == ECHILD)
|
||||||
|
ee_printf("errno=No such child %d\n", res->port.pid);
|
||||||
|
if (errno == EINTR)
|
||||||
|
ee_printf("errno=Interrupted\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#else /* no standard multicore implementation */
|
||||||
|
#error \
|
||||||
|
"Please implement multicore functionality in core_portme.c to use multiple contexts."
|
||||||
|
#endif /* multithread implementations */
|
||||||
|
#endif
|
314
riscv-coremark/coremark/posix/core_portme.h
Normal file
314
riscv-coremark/coremark/posix/core_portme.h
Normal file
@ -0,0 +1,314 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2018 Embedded Microprocessor Benchmark Consortium (EEMBC)
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
Original Author: Shay Gal-on
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Topic: Description
|
||||||
|
This file contains configuration constants required to execute on
|
||||||
|
different platforms
|
||||||
|
*/
|
||||||
|
#ifndef CORE_PORTME_H
|
||||||
|
#define CORE_PORTME_H
|
||||||
|
|
||||||
|
#include "core_portme_posix_overrides.h"
|
||||||
|
|
||||||
|
/************************/
|
||||||
|
/* Data types and settings */
|
||||||
|
/************************/
|
||||||
|
/* Configuration: HAS_FLOAT
|
||||||
|
Define to 1 if the platform supports floating point.
|
||||||
|
*/
|
||||||
|
#ifndef HAS_FLOAT
|
||||||
|
#define HAS_FLOAT 1
|
||||||
|
#endif
|
||||||
|
/* Configuration: HAS_TIME_H
|
||||||
|
Define to 1 if platform has the time.h header file,
|
||||||
|
and implementation of functions thereof.
|
||||||
|
*/
|
||||||
|
#ifndef HAS_TIME_H
|
||||||
|
#define HAS_TIME_H 1
|
||||||
|
#endif
|
||||||
|
/* Configuration: USE_CLOCK
|
||||||
|
Define to 1 if platform has the time.h header file,
|
||||||
|
and implementation of functions thereof.
|
||||||
|
*/
|
||||||
|
#ifndef USE_CLOCK
|
||||||
|
#define USE_CLOCK 0
|
||||||
|
#endif
|
||||||
|
/* Configuration: HAS_STDIO
|
||||||
|
Define to 1 if the platform has stdio.h.
|
||||||
|
*/
|
||||||
|
#ifndef HAS_STDIO
|
||||||
|
#define HAS_STDIO 1
|
||||||
|
#endif
|
||||||
|
/* Configuration: HAS_PRINTF
|
||||||
|
Define to 1 if the platform has stdio.h and implements the printf
|
||||||
|
function.
|
||||||
|
*/
|
||||||
|
#ifndef HAS_PRINTF
|
||||||
|
#define HAS_PRINTF 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Configuration: CORE_TICKS
|
||||||
|
Define type of return from the timing functions.
|
||||||
|
*/
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#include <windows.h>
|
||||||
|
typedef size_t CORE_TICKS;
|
||||||
|
#elif HAS_TIME_H
|
||||||
|
#include <time.h>
|
||||||
|
typedef clock_t CORE_TICKS;
|
||||||
|
#else
|
||||||
|
#error \
|
||||||
|
"Please define type of CORE_TICKS and implement start_time, end_time get_time and time_in_secs functions!"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Definitions: COMPILER_VERSION, COMPILER_FLAGS, MEM_LOCATION
|
||||||
|
Initialize these strings per platform
|
||||||
|
*/
|
||||||
|
#ifndef COMPILER_VERSION
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#define COMPILER_VERSION "GCC"__VERSION__
|
||||||
|
#else
|
||||||
|
#define COMPILER_VERSION "Please put compiler version here (e.g. gcc 4.1)"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#ifndef COMPILER_FLAGS
|
||||||
|
#define COMPILER_FLAGS \
|
||||||
|
FLAGS_STR /* "Please put compiler flags here (e.g. -o3)" */
|
||||||
|
#endif
|
||||||
|
#ifndef MEM_LOCATION
|
||||||
|
#define MEM_LOCATION \
|
||||||
|
"Please put data memory location here\n\t\t\t(e.g. code in flash, data " \
|
||||||
|
"on heap etc)"
|
||||||
|
#define MEM_LOCATION_UNSPEC 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/* Data Types:
|
||||||
|
To avoid compiler issues, define the data types that need ot be used for
|
||||||
|
8b, 16b and 32b in <core_portme.h>.
|
||||||
|
|
||||||
|
*Imprtant*:
|
||||||
|
ee_ptr_int needs to be the data type used to hold pointers, otherwise
|
||||||
|
coremark may fail!!!
|
||||||
|
*/
|
||||||
|
typedef signed short ee_s16;
|
||||||
|
typedef unsigned short ee_u16;
|
||||||
|
typedef signed int ee_s32;
|
||||||
|
typedef double ee_f32;
|
||||||
|
typedef unsigned char ee_u8;
|
||||||
|
typedef unsigned int ee_u32;
|
||||||
|
typedef uintptr_t ee_ptr_int;
|
||||||
|
typedef size_t ee_size_t;
|
||||||
|
/* align an offset to point to a 32b value */
|
||||||
|
#define align_mem(x) (void *)(4 + (((ee_ptr_int)(x)-1) & ~3))
|
||||||
|
|
||||||
|
/* Configuration: SEED_METHOD
|
||||||
|
Defines method to get seed values that cannot be computed at compile
|
||||||
|
time.
|
||||||
|
|
||||||
|
Valid values:
|
||||||
|
SEED_ARG - from command line.
|
||||||
|
SEED_FUNC - from a system function.
|
||||||
|
SEED_VOLATILE - from volatile variables.
|
||||||
|
*/
|
||||||
|
#ifndef SEED_METHOD
|
||||||
|
#define SEED_METHOD SEED_ARG
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Configuration: MEM_METHOD
|
||||||
|
Defines method to get a block of memry.
|
||||||
|
|
||||||
|
Valid values:
|
||||||
|
MEM_MALLOC - for platforms that implement malloc and have malloc.h.
|
||||||
|
MEM_STATIC - to use a static memory array.
|
||||||
|
MEM_STACK - to allocate the data block on the stack (NYI).
|
||||||
|
*/
|
||||||
|
#ifndef MEM_METHOD
|
||||||
|
#define MEM_METHOD MEM_MALLOC
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Configuration: MULTITHREAD
|
||||||
|
Define for parallel execution
|
||||||
|
|
||||||
|
Valid values:
|
||||||
|
1 - only one context (default).
|
||||||
|
N>1 - will execute N copies in parallel.
|
||||||
|
|
||||||
|
Note:
|
||||||
|
If this flag is defined to more then 1, an implementation for launching
|
||||||
|
parallel contexts must be defined.
|
||||||
|
|
||||||
|
Two sample implementations are provided. Use <USE_PTHREAD> or <USE_FORK>
|
||||||
|
to enable them.
|
||||||
|
|
||||||
|
It is valid to have a different implementation of <core_start_parallel>
|
||||||
|
and <core_end_parallel> in <core_portme.c>, to fit a particular architecture.
|
||||||
|
*/
|
||||||
|
#ifndef MULTITHREAD
|
||||||
|
#define MULTITHREAD 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Configuration: USE_PTHREAD
|
||||||
|
Sample implementation for launching parallel contexts
|
||||||
|
This implementation uses pthread_thread_create and pthread_join.
|
||||||
|
|
||||||
|
Valid values:
|
||||||
|
0 - Do not use pthreads API.
|
||||||
|
1 - Use pthreads API
|
||||||
|
|
||||||
|
Note:
|
||||||
|
This flag only matters if MULTITHREAD has been defined to a value
|
||||||
|
greater then 1.
|
||||||
|
*/
|
||||||
|
#ifndef USE_PTHREAD
|
||||||
|
#define USE_PTHREAD 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Configuration: USE_FORK
|
||||||
|
Sample implementation for launching parallel contexts
|
||||||
|
This implementation uses fork, waitpid, shmget,shmat and shmdt.
|
||||||
|
|
||||||
|
Valid values:
|
||||||
|
0 - Do not use fork API.
|
||||||
|
1 - Use fork API
|
||||||
|
|
||||||
|
Note:
|
||||||
|
This flag only matters if MULTITHREAD has been defined to a value
|
||||||
|
greater then 1.
|
||||||
|
*/
|
||||||
|
#ifndef USE_FORK
|
||||||
|
#define USE_FORK 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Configuration: USE_SOCKET
|
||||||
|
Sample implementation for launching parallel contexts
|
||||||
|
This implementation uses fork, socket, sendto and recvfrom
|
||||||
|
|
||||||
|
Valid values:
|
||||||
|
0 - Do not use fork and sockets API.
|
||||||
|
1 - Use fork and sockets API
|
||||||
|
|
||||||
|
Note:
|
||||||
|
This flag only matters if MULTITHREAD has been defined to a value
|
||||||
|
greater then 1.
|
||||||
|
*/
|
||||||
|
#ifndef USE_SOCKET
|
||||||
|
#define USE_SOCKET 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Configuration: MAIN_HAS_NOARGC
|
||||||
|
Needed if platform does not support getting arguments to main.
|
||||||
|
|
||||||
|
Valid values:
|
||||||
|
0 - argc/argv to main is supported
|
||||||
|
1 - argc/argv to main is not supported
|
||||||
|
*/
|
||||||
|
#ifndef MAIN_HAS_NOARGC
|
||||||
|
#define MAIN_HAS_NOARGC 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Configuration: MAIN_HAS_NORETURN
|
||||||
|
Needed if platform does not support returning a value from main.
|
||||||
|
|
||||||
|
Valid values:
|
||||||
|
0 - main returns an int, and return value will be 0.
|
||||||
|
1 - platform does not support returning a value from main
|
||||||
|
*/
|
||||||
|
#ifndef MAIN_HAS_NORETURN
|
||||||
|
#define MAIN_HAS_NORETURN 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Variable: default_num_contexts
|
||||||
|
Number of contexts to spawn in multicore context.
|
||||||
|
Override this global value to change number of contexts used.
|
||||||
|
|
||||||
|
Note:
|
||||||
|
This value may not be set higher then the <MULTITHREAD> define.
|
||||||
|
|
||||||
|
To experiment, you can set the <MULTITHREAD> define to the highest value
|
||||||
|
expected, and use argc/argv in the <portable_init> to set this value from the
|
||||||
|
command line.
|
||||||
|
*/
|
||||||
|
extern ee_u32 default_num_contexts;
|
||||||
|
|
||||||
|
#if (MULTITHREAD > 1)
|
||||||
|
#if USE_PTHREAD
|
||||||
|
#include <pthread.h>
|
||||||
|
#define PARALLEL_METHOD "PThreads"
|
||||||
|
#elif USE_FORK
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <sys/shm.h>
|
||||||
|
#include <string.h> /* for memcpy */
|
||||||
|
#define PARALLEL_METHOD "Fork"
|
||||||
|
#elif USE_SOCKET
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#define PARALLEL_METHOD "Sockets"
|
||||||
|
#else
|
||||||
|
#define PARALLEL_METHOD "Proprietary"
|
||||||
|
#error \
|
||||||
|
"Please implement multicore functionality in core_portme.c to use multiple contexts."
|
||||||
|
#endif /* Method for multithreading */
|
||||||
|
#endif /* MULTITHREAD > 1 */
|
||||||
|
|
||||||
|
typedef struct CORE_PORTABLE_S
|
||||||
|
{
|
||||||
|
#if (MULTITHREAD > 1)
|
||||||
|
#if USE_PTHREAD
|
||||||
|
pthread_t thread;
|
||||||
|
#elif USE_FORK
|
||||||
|
pid_t pid;
|
||||||
|
int shmid;
|
||||||
|
void *shm;
|
||||||
|
#elif USE_SOCKET
|
||||||
|
pid_t pid;
|
||||||
|
int sock;
|
||||||
|
struct sockaddr_in sa;
|
||||||
|
#endif /* Method for multithreading */
|
||||||
|
#endif /* MULTITHREAD>1 */
|
||||||
|
ee_u8 portable_id;
|
||||||
|
} core_portable;
|
||||||
|
|
||||||
|
/* target specific init/fini */
|
||||||
|
void portable_init(core_portable *p, int *argc, char *argv[]);
|
||||||
|
void portable_fini(core_portable *p);
|
||||||
|
|
||||||
|
#if (SEED_METHOD == SEED_VOLATILE)
|
||||||
|
#if (VALIDATION_RUN || PERFORMANCE_RUN || PROFILE_RUN)
|
||||||
|
#define RUN_TYPE_FLAG 1
|
||||||
|
#else
|
||||||
|
#if (TOTAL_DATA_SIZE == 1200)
|
||||||
|
#define PROFILE_RUN 1
|
||||||
|
#else
|
||||||
|
#define PERFORMANCE_RUN 1
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif /* SEED_METHOD==SEED_VOLATILE */
|
||||||
|
|
||||||
|
#endif /* CORE_PORTME_H */
|
151
riscv-coremark/coremark/posix/core_portme.mak
Executable file
151
riscv-coremark/coremark/posix/core_portme.mak
Executable file
@ -0,0 +1,151 @@
|
|||||||
|
# Copyright 2018 Embedded Microprocessor Benchmark Consortium (EEMBC)
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
# Original Author: Shay Gal-on
|
||||||
|
|
||||||
|
#File: core_portme.mak
|
||||||
|
|
||||||
|
# Flag: OUTFLAG
|
||||||
|
# Use this flag to define how to to get an executable (e.g -o)
|
||||||
|
OUTFLAG= -o
|
||||||
|
# Flag: CC
|
||||||
|
# Use this flag to define compiler to use
|
||||||
|
CC?= cc
|
||||||
|
# Flag: CFLAGS
|
||||||
|
# Use this flag to define compiler options. Note, you can add compiler options from the command line using XCFLAGS="other flags"
|
||||||
|
PORT_CFLAGS = -O2
|
||||||
|
FLAGS_STR = "$(PORT_CFLAGS) $(XCFLAGS) $(XLFLAGS) $(LFLAGS_END)"
|
||||||
|
CFLAGS = $(PORT_CFLAGS) -I$(PORT_DIR) -Iposix -I. -DFLAGS_STR=\"$(FLAGS_STR)\"
|
||||||
|
# Flag: NO_LIBRT
|
||||||
|
# Define if the platform does not provide a librt
|
||||||
|
ifndef NO_LIBRT
|
||||||
|
#Flag: LFLAGS_END
|
||||||
|
# Define any libraries needed for linking or other flags that should come at the end of the link line (e.g. linker scripts).
|
||||||
|
# Note: On certain platforms, the default clock_gettime implementation is supported but requires linking of librt.
|
||||||
|
LFLAGS_END += -lrt
|
||||||
|
endif
|
||||||
|
# Flag: PORT_SRCS
|
||||||
|
# Port specific source files can be added here
|
||||||
|
PORT_SRCS = posix/core_portme.c
|
||||||
|
vpath %.c posix
|
||||||
|
vpath %.h posix
|
||||||
|
vpath %.mak posix
|
||||||
|
# Flag: EXTRA_DEPENDS
|
||||||
|
# Port specific extra build dependencies.
|
||||||
|
# Some ports inherit from us, so ensure this Makefile is always a dependency.
|
||||||
|
EXTRA_DEPENDS += posix/core_portme.mak
|
||||||
|
# Flag: LOAD
|
||||||
|
# Define this flag if you need to load to a target, as in a cross compile environment.
|
||||||
|
|
||||||
|
# Flag: RUN
|
||||||
|
# Define this flag if running does not consist of simple invocation of the binary.
|
||||||
|
# In a cross compile environment, you need to define this.
|
||||||
|
|
||||||
|
#For flashing and using a tera term macro, you could use
|
||||||
|
#LOAD = flash ADDR
|
||||||
|
#RUN = ttpmacro coremark.ttl
|
||||||
|
|
||||||
|
#For copying to target and executing via SSH connection, you could use
|
||||||
|
#LOAD = scp $(OUTFILE) user@target:~
|
||||||
|
#RUN = ssh user@target -c
|
||||||
|
|
||||||
|
#For native compilation and execution
|
||||||
|
LOAD = echo Loading done
|
||||||
|
RUN =
|
||||||
|
|
||||||
|
OEXT = .o
|
||||||
|
EXE = .exe
|
||||||
|
|
||||||
|
# Flag: SEPARATE_COMPILE
|
||||||
|
# Define if you need to separate compilation from link stage.
|
||||||
|
# In this case, you also need to define below how to create an object file, and how to link.
|
||||||
|
ifdef SEPARATE_COMPILE
|
||||||
|
|
||||||
|
LD = gcc
|
||||||
|
OBJOUT = -o
|
||||||
|
LFLAGS =
|
||||||
|
OFLAG = -o
|
||||||
|
COUT = -c
|
||||||
|
# Flag: PORT_OBJS
|
||||||
|
# Port specific object files can be added here
|
||||||
|
PORT_OBJS = $(PORT_DIR)/core_portme$(OEXT)
|
||||||
|
PORT_CLEAN = *$(OEXT)
|
||||||
|
|
||||||
|
$(OPATH)%$(OEXT) : %.c
|
||||||
|
$(CC) $(CFLAGS) $(XCFLAGS) $(COUT) $< $(OBJOUT) $@
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Target: port_prebuild
|
||||||
|
# Generate any files that are needed before actual build starts.
|
||||||
|
# E.g. generate profile guidance files. Sample PGO generation for gcc enabled with PGO=1
|
||||||
|
# - First, check if PGO was defined on the command line, if so, need to add -fprofile-use to compile line.
|
||||||
|
# - Second, if PGO reference has not yet been generated, add a step to the prebuild that will build a profile-generate version and run it.
|
||||||
|
# Note - Using REBUILD=1
|
||||||
|
#
|
||||||
|
# Use make PGO=1 to invoke this sample processing.
|
||||||
|
|
||||||
|
ifdef PGO
|
||||||
|
ifeq (,$(findstring $(PGO),gen))
|
||||||
|
PGO_STAGE=build_pgo_gcc
|
||||||
|
CFLAGS+=-fprofile-use
|
||||||
|
endif
|
||||||
|
PORT_CLEAN+=*.gcda *.gcno gmon.out
|
||||||
|
endif
|
||||||
|
|
||||||
|
.PHONY: port_prebuild
|
||||||
|
port_prebuild: $(PGO_STAGE)
|
||||||
|
|
||||||
|
.PHONY: build_pgo_gcc
|
||||||
|
build_pgo_gcc:
|
||||||
|
$(MAKE) PGO=gen XCFLAGS="$(XCFLAGS) -fprofile-generate -DTOTAL_DATA_SIZE=1200" ITERATIONS=10 gen_pgo_data REBUILD=1
|
||||||
|
|
||||||
|
# Target: port_postbuild
|
||||||
|
# Generate any files that are needed after actual build end.
|
||||||
|
# E.g. change format to srec, bin, zip in order to be able to load into flash
|
||||||
|
.PHONY: port_postbuild
|
||||||
|
port_postbuild:
|
||||||
|
|
||||||
|
# Target: port_postrun
|
||||||
|
# Do platform specific after run stuff.
|
||||||
|
# E.g. reset the board, backup the logfiles etc.
|
||||||
|
.PHONY: port_postrun
|
||||||
|
port_postrun:
|
||||||
|
|
||||||
|
# Target: port_prerun
|
||||||
|
# Do platform specific after run stuff.
|
||||||
|
# E.g. reset the board, backup the logfiles etc.
|
||||||
|
.PHONY: port_prerun
|
||||||
|
port_prerun:
|
||||||
|
|
||||||
|
# Target: port_postload
|
||||||
|
# Do platform specific after load stuff.
|
||||||
|
# E.g. reset the reset power to the flash eraser
|
||||||
|
.PHONY: port_postload
|
||||||
|
port_postload:
|
||||||
|
|
||||||
|
# Target: port_preload
|
||||||
|
# Do platform specific before load stuff.
|
||||||
|
# E.g. reset the reset power to the flash eraser
|
||||||
|
.PHONY: port_preload
|
||||||
|
port_preload:
|
||||||
|
|
||||||
|
# FLAG: OPATH
|
||||||
|
# Path to the output folder. Default - current folder.
|
||||||
|
OPATH = ./
|
||||||
|
MKDIR = mkdir -p
|
||||||
|
|
||||||
|
# FLAG: PERL
|
||||||
|
# Define perl executable to calculate the geomean if running separate.
|
||||||
|
PERL=/usr/bin/perl
|
28
riscv-coremark/coremark/posix/core_portme_posix_overrides.h
Normal file
28
riscv-coremark/coremark/posix/core_portme_posix_overrides.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2018 Embedded Microprocessor Benchmark Consortium (EEMBC)
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
Original Author: Shay Gal-on
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Topic: Description
|
||||||
|
This file contains additional configuration constants required to execute on
|
||||||
|
different platforms over and above the POSIX defaults
|
||||||
|
*/
|
||||||
|
#ifndef CORE_PORTME_POSIX_OVERRIDES_H
|
||||||
|
#define CORE_PORTME_POSIX_OVERRIDES_H
|
||||||
|
|
||||||
|
/* None by default */
|
||||||
|
|
||||||
|
#endif
|
18
riscv-coremark/coremark/rtems/core_portme.mak
Normal file
18
riscv-coremark/coremark/rtems/core_portme.mak
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Copyright 2018 Embedded Microprocessor Benchmark Consortium (EEMBC)
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
# Original Author: Shay Gal-on
|
||||||
|
|
||||||
|
NO_LIBRT = 1
|
||||||
|
include posix/core_portme.mak
|
63
riscv-coremark/coremark/rtems/init.c
Normal file
63
riscv-coremark/coremark/rtems/init.c
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
/*-
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021 Hesham Almatary
|
||||||
|
*
|
||||||
|
* This software was developed by SRI International and the University of
|
||||||
|
* Cambridge Computer Laboratory (Department of Computer Science and
|
||||||
|
* Technology) under DARPA contract HR0011-18-C-0016 ("ECATS"), as part of the
|
||||||
|
* DARPA SSITH research programme.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <bsp.h>
|
||||||
|
|
||||||
|
int main(
|
||||||
|
int argc,
|
||||||
|
void **args
|
||||||
|
);
|
||||||
|
|
||||||
|
rtems_task Init(
|
||||||
|
rtems_task_argument ignored
|
||||||
|
);
|
||||||
|
|
||||||
|
rtems_task Init(
|
||||||
|
rtems_task_argument ignored
|
||||||
|
)
|
||||||
|
{
|
||||||
|
int ret = main(0, NULL);
|
||||||
|
exit(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* configuration information */
|
||||||
|
#define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
|
||||||
|
#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
|
||||||
|
|
||||||
|
#define CONFIGURE_MAXIMUM_TASKS 20
|
||||||
|
|
||||||
|
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
|
||||||
|
|
||||||
|
#define CONFIGURE_INIT
|
||||||
|
|
||||||
|
#include <rtems/confdefs.h>
|
153
riscv-coremark/coremark/simple/core_portme.c
Executable file → Normal file
153
riscv-coremark/coremark/simple/core_portme.c
Executable file → Normal file
@ -21,108 +21,129 @@ Original Author: Shay Gal-on
|
|||||||
#include "coremark.h"
|
#include "coremark.h"
|
||||||
|
|
||||||
#if VALIDATION_RUN
|
#if VALIDATION_RUN
|
||||||
volatile ee_s32 seed1_volatile=0x3415;
|
volatile ee_s32 seed1_volatile = 0x3415;
|
||||||
volatile ee_s32 seed2_volatile=0x3415;
|
volatile ee_s32 seed2_volatile = 0x3415;
|
||||||
volatile ee_s32 seed3_volatile=0x66;
|
volatile ee_s32 seed3_volatile = 0x66;
|
||||||
#endif
|
#endif
|
||||||
#if PERFORMANCE_RUN
|
#if PERFORMANCE_RUN
|
||||||
volatile ee_s32 seed1_volatile=0x0;
|
volatile ee_s32 seed1_volatile = 0x0;
|
||||||
volatile ee_s32 seed2_volatile=0x0;
|
volatile ee_s32 seed2_volatile = 0x0;
|
||||||
volatile ee_s32 seed3_volatile=0x66;
|
volatile ee_s32 seed3_volatile = 0x66;
|
||||||
#endif
|
#endif
|
||||||
#if PROFILE_RUN
|
#if PROFILE_RUN
|
||||||
volatile ee_s32 seed1_volatile=0x8;
|
volatile ee_s32 seed1_volatile = 0x8;
|
||||||
volatile ee_s32 seed2_volatile=0x8;
|
volatile ee_s32 seed2_volatile = 0x8;
|
||||||
volatile ee_s32 seed3_volatile=0x8;
|
volatile ee_s32 seed3_volatile = 0x8;
|
||||||
#endif
|
#endif
|
||||||
volatile ee_s32 seed4_volatile=ITERATIONS;
|
volatile ee_s32 seed4_volatile = ITERATIONS;
|
||||||
volatile ee_s32 seed5_volatile=0;
|
volatile ee_s32 seed5_volatile = 0;
|
||||||
/* Porting : Timing functions
|
/* Porting : Timing functions
|
||||||
How to capture time and convert to seconds must be ported to whatever is supported by the platform.
|
How to capture time and convert to seconds must be ported to whatever is
|
||||||
e.g. Read value from on board RTC, read value from cpu clock cycles performance counter etc.
|
supported by the platform. e.g. Read value from on board RTC, read value from
|
||||||
Sample implementation for standard time.h and windows.h definitions included.
|
cpu clock cycles performance counter etc. Sample implementation for standard
|
||||||
|
time.h and windows.h definitions included.
|
||||||
*/
|
*/
|
||||||
/* Define : TIMER_RES_DIVIDER
|
/* Define : TIMER_RES_DIVIDER
|
||||||
Divider to trade off timer resolution and total time that can be measured.
|
Divider to trade off timer resolution and total time that can be
|
||||||
|
measured.
|
||||||
|
|
||||||
Use lower values to increase resolution, but make sure that overflow does not occur.
|
Use lower values to increase resolution, but make sure that overflow
|
||||||
If there are issues with the return value overflowing, increase this value.
|
does not occur. If there are issues with the return value overflowing,
|
||||||
*/
|
increase this value.
|
||||||
#define NSECS_PER_SEC CLOCKS_PER_SEC
|
*/
|
||||||
#define CORETIMETYPE clock_t
|
#define NSECS_PER_SEC CLOCKS_PER_SEC
|
||||||
#define GETMYTIME(_t) (*_t=clock())
|
#define CORETIMETYPE clock_t
|
||||||
#define MYTIMEDIFF(fin,ini) ((fin)-(ini))
|
#define GETMYTIME(_t) (*_t = clock())
|
||||||
#define TIMER_RES_DIVIDER 1
|
#define MYTIMEDIFF(fin, ini) ((fin) - (ini))
|
||||||
|
#define TIMER_RES_DIVIDER 1
|
||||||
#define SAMPLE_TIME_IMPLEMENTATION 1
|
#define SAMPLE_TIME_IMPLEMENTATION 1
|
||||||
#define EE_TICKS_PER_SEC (NSECS_PER_SEC / TIMER_RES_DIVIDER)
|
#define EE_TICKS_PER_SEC (NSECS_PER_SEC / TIMER_RES_DIVIDER)
|
||||||
|
|
||||||
/** Define Host specific (POSIX), or target specific global time variables. */
|
/** Define Host specific (POSIX), or target specific global time variables. */
|
||||||
static CORETIMETYPE start_time_val, stop_time_val;
|
static CORETIMETYPE start_time_val, stop_time_val;
|
||||||
|
|
||||||
/* Function : start_time
|
/* Function : start_time
|
||||||
This function will be called right before starting the timed portion of the benchmark.
|
This function will be called right before starting the timed portion of
|
||||||
|
the benchmark.
|
||||||
|
|
||||||
Implementation may be capturing a system timer (as implemented in the example code)
|
Implementation may be capturing a system timer (as implemented in the
|
||||||
or zeroing some system parameters - e.g. setting the cpu clocks cycles to 0.
|
example code) or zeroing some system parameters - e.g. setting the cpu clocks
|
||||||
|
cycles to 0.
|
||||||
*/
|
*/
|
||||||
void start_time(void) {
|
void
|
||||||
GETMYTIME(&start_time_val );
|
start_time(void)
|
||||||
|
{
|
||||||
|
GETMYTIME(&start_time_val);
|
||||||
}
|
}
|
||||||
/* Function : stop_time
|
/* Function : stop_time
|
||||||
This function will be called right after ending the timed portion of the benchmark.
|
This function will be called right after ending the timed portion of the
|
||||||
|
benchmark.
|
||||||
|
|
||||||
Implementation may be capturing a system timer (as implemented in the example code)
|
Implementation may be capturing a system timer (as implemented in the
|
||||||
or other system parameters - e.g. reading the current value of cpu cycles counter.
|
example code) or other system parameters - e.g. reading the current value of
|
||||||
|
cpu cycles counter.
|
||||||
*/
|
*/
|
||||||
void stop_time(void) {
|
void
|
||||||
GETMYTIME(&stop_time_val );
|
stop_time(void)
|
||||||
|
{
|
||||||
|
GETMYTIME(&stop_time_val);
|
||||||
}
|
}
|
||||||
/* Function : get_time
|
/* Function : get_time
|
||||||
Return an abstract "ticks" number that signifies time on the system.
|
Return an abstract "ticks" number that signifies time on the system.
|
||||||
|
|
||||||
Actual value returned may be cpu cycles, milliseconds or any other value,
|
Actual value returned may be cpu cycles, milliseconds or any other
|
||||||
as long as it can be converted to seconds by <time_in_secs>.
|
value, as long as it can be converted to seconds by <time_in_secs>. This
|
||||||
This methodology is taken to accomodate any hardware or simulated platform.
|
methodology is taken to accomodate any hardware or simulated platform. The
|
||||||
The sample implementation returns millisecs by default,
|
sample implementation returns millisecs by default, and the resolution is
|
||||||
and the resolution is controlled by <TIMER_RES_DIVIDER>
|
controlled by <TIMER_RES_DIVIDER>
|
||||||
*/
|
*/
|
||||||
CORE_TICKS get_time(void) {
|
CORE_TICKS
|
||||||
CORE_TICKS elapsed=(CORE_TICKS)(MYTIMEDIFF(stop_time_val, start_time_val));
|
get_time(void)
|
||||||
return elapsed;
|
{
|
||||||
|
CORE_TICKS elapsed
|
||||||
|
= (CORE_TICKS)(MYTIMEDIFF(stop_time_val, start_time_val));
|
||||||
|
return elapsed;
|
||||||
}
|
}
|
||||||
/* Function : time_in_secs
|
/* Function : time_in_secs
|
||||||
Convert the value returned by get_time to seconds.
|
Convert the value returned by get_time to seconds.
|
||||||
|
|
||||||
The <secs_ret> type is used to accomodate systems with no support for floating point.
|
The <secs_ret> type is used to accomodate systems with no support for
|
||||||
Default implementation implemented by the EE_TICKS_PER_SEC macro above.
|
floating point. Default implementation implemented by the EE_TICKS_PER_SEC
|
||||||
|
macro above.
|
||||||
*/
|
*/
|
||||||
secs_ret time_in_secs(CORE_TICKS ticks) {
|
secs_ret
|
||||||
secs_ret retval=((secs_ret)ticks) / (secs_ret)EE_TICKS_PER_SEC;
|
time_in_secs(CORE_TICKS ticks)
|
||||||
return retval;
|
{
|
||||||
|
secs_ret retval = ((secs_ret)ticks) / (secs_ret)EE_TICKS_PER_SEC;
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
ee_u32 default_num_contexts=1;
|
ee_u32 default_num_contexts = 1;
|
||||||
|
|
||||||
/* Function : portable_init
|
/* Function : portable_init
|
||||||
Target specific initialization code
|
Target specific initialization code
|
||||||
Test for some common mistakes.
|
Test for some common mistakes.
|
||||||
*/
|
*/
|
||||||
void portable_init(core_portable *p, int *argc, char *argv[])
|
void
|
||||||
|
portable_init(core_portable *p, int *argc, char *argv[])
|
||||||
{
|
{
|
||||||
if (sizeof(ee_ptr_int) != sizeof(ee_u8 *)) {
|
if (sizeof(ee_ptr_int) != sizeof(ee_u8 *))
|
||||||
ee_printf("ERROR! Please define ee_ptr_int to a type that holds a pointer!\n");
|
{
|
||||||
}
|
ee_printf(
|
||||||
if (sizeof(ee_u32) != 4) {
|
"ERROR! Please define ee_ptr_int to a type that holds a "
|
||||||
ee_printf("ERROR! Please define ee_u32 to a 32b unsigned type!\n");
|
"pointer!\n");
|
||||||
}
|
}
|
||||||
p->portable_id=1;
|
if (sizeof(ee_u32) != 4)
|
||||||
|
{
|
||||||
|
ee_printf("ERROR! Please define ee_u32 to a 32b unsigned type!\n");
|
||||||
|
}
|
||||||
|
p->portable_id = 1;
|
||||||
}
|
}
|
||||||
/* Function : portable_fini
|
/* Function : portable_fini
|
||||||
Target specific final code
|
Target specific final code
|
||||||
*/
|
*/
|
||||||
void portable_fini(core_portable *p)
|
void
|
||||||
|
portable_fini(core_portable *p)
|
||||||
{
|
{
|
||||||
p->portable_id=0;
|
p->portable_id = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
176
riscv-coremark/coremark/simple/core_portme.h
Executable file → Normal file
176
riscv-coremark/coremark/simple/core_portme.h
Executable file → Normal file
@ -17,176 +17,188 @@ Original Author: Shay Gal-on
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* Topic : Description
|
/* Topic : Description
|
||||||
This file contains configuration constants required to execute on different platforms
|
This file contains configuration constants required to execute on
|
||||||
|
different platforms
|
||||||
*/
|
*/
|
||||||
#ifndef CORE_PORTME_H
|
#ifndef CORE_PORTME_H
|
||||||
#define CORE_PORTME_H
|
#define CORE_PORTME_H
|
||||||
/************************/
|
/************************/
|
||||||
/* Data types and settings */
|
/* Data types and settings */
|
||||||
/************************/
|
/************************/
|
||||||
/* Configuration : HAS_FLOAT
|
/* Configuration : HAS_FLOAT
|
||||||
Define to 1 if the platform supports floating point.
|
Define to 1 if the platform supports floating point.
|
||||||
*/
|
*/
|
||||||
#ifndef HAS_FLOAT
|
#ifndef HAS_FLOAT
|
||||||
#define HAS_FLOAT 1
|
#define HAS_FLOAT 1
|
||||||
#endif
|
#endif
|
||||||
/* Configuration : HAS_TIME_H
|
/* Configuration : HAS_TIME_H
|
||||||
Define to 1 if platform has the time.h header file,
|
Define to 1 if platform has the time.h header file,
|
||||||
and implementation of functions thereof.
|
and implementation of functions thereof.
|
||||||
*/
|
*/
|
||||||
#ifndef HAS_TIME_H
|
#ifndef HAS_TIME_H
|
||||||
#define HAS_TIME_H 1
|
#define HAS_TIME_H 1
|
||||||
#endif
|
#endif
|
||||||
/* Configuration : USE_CLOCK
|
/* Configuration : USE_CLOCK
|
||||||
Define to 1 if platform has the time.h header file,
|
Define to 1 if platform has the time.h header file,
|
||||||
and implementation of functions thereof.
|
and implementation of functions thereof.
|
||||||
*/
|
*/
|
||||||
#ifndef USE_CLOCK
|
#ifndef USE_CLOCK
|
||||||
#define USE_CLOCK 1
|
#define USE_CLOCK 1
|
||||||
#endif
|
#endif
|
||||||
/* Configuration : HAS_STDIO
|
/* Configuration : HAS_STDIO
|
||||||
Define to 1 if the platform has stdio.h.
|
Define to 1 if the platform has stdio.h.
|
||||||
*/
|
*/
|
||||||
#ifndef HAS_STDIO
|
#ifndef HAS_STDIO
|
||||||
#define HAS_STDIO 1
|
#define HAS_STDIO 1
|
||||||
#endif
|
#endif
|
||||||
/* Configuration : HAS_PRINTF
|
/* Configuration : HAS_PRINTF
|
||||||
Define to 1 if the platform has stdio.h and implements the printf function.
|
Define to 1 if the platform has stdio.h and implements the printf
|
||||||
|
function.
|
||||||
*/
|
*/
|
||||||
#ifndef HAS_PRINTF
|
#ifndef HAS_PRINTF
|
||||||
#define HAS_PRINTF 1
|
#define HAS_PRINTF 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Configuration : CORE_TICKS
|
/* Configuration : CORE_TICKS
|
||||||
Define type of return from the timing functions.
|
Define type of return from the timing functions.
|
||||||
*/
|
*/
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
typedef clock_t CORE_TICKS;
|
typedef clock_t CORE_TICKS;
|
||||||
|
|
||||||
/* Definitions : COMPILER_VERSION, COMPILER_FLAGS, MEM_LOCATION
|
/* Definitions : COMPILER_VERSION, COMPILER_FLAGS, MEM_LOCATION
|
||||||
Initialize these strings per platform
|
Initialize these strings per platform
|
||||||
*/
|
*/
|
||||||
#ifndef COMPILER_VERSION
|
#ifndef COMPILER_VERSION
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
#define COMPILER_VERSION "GCC"__VERSION__
|
#define COMPILER_VERSION "GCC"__VERSION__
|
||||||
#else
|
#else
|
||||||
#define COMPILER_VERSION "Please put compiler version here (e.g. gcc 4.1)"
|
#define COMPILER_VERSION "Please put compiler version here (e.g. gcc 4.1)"
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
#ifndef COMPILER_FLAGS
|
|
||||||
#define COMPILER_FLAGS FLAGS_STR /* "Please put compiler flags here (e.g. -o3)" */
|
|
||||||
#endif
|
#endif
|
||||||
#ifndef MEM_LOCATION
|
#ifndef COMPILER_FLAGS
|
||||||
#define MEM_LOCATION "STACK"
|
#define COMPILER_FLAGS \
|
||||||
|
FLAGS_STR /* "Please put compiler flags here (e.g. -o3)" */
|
||||||
|
#endif
|
||||||
|
#ifndef MEM_LOCATION
|
||||||
|
#define MEM_LOCATION "STACK"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Data Types :
|
/* Data Types :
|
||||||
To avoid compiler issues, define the data types that need ot be used for 8b, 16b and 32b in <core_portme.h>.
|
To avoid compiler issues, define the data types that need ot be used for
|
||||||
|
8b, 16b and 32b in <core_portme.h>.
|
||||||
*Imprtant* :
|
|
||||||
ee_ptr_int needs to be the data type used to hold pointers, otherwise coremark may fail!!!
|
*Imprtant* :
|
||||||
|
ee_ptr_int needs to be the data type used to hold pointers, otherwise
|
||||||
|
coremark may fail!!!
|
||||||
*/
|
*/
|
||||||
typedef signed short ee_s16;
|
typedef signed short ee_s16;
|
||||||
typedef unsigned short ee_u16;
|
typedef unsigned short ee_u16;
|
||||||
typedef signed int ee_s32;
|
typedef signed int ee_s32;
|
||||||
typedef double ee_f32;
|
typedef double ee_f32;
|
||||||
typedef unsigned char ee_u8;
|
typedef unsigned char ee_u8;
|
||||||
typedef unsigned int ee_u32;
|
typedef unsigned int ee_u32;
|
||||||
typedef ee_u32 ee_ptr_int;
|
typedef ee_u32 ee_ptr_int;
|
||||||
typedef size_t ee_size_t;
|
typedef size_t ee_size_t;
|
||||||
/* align_mem :
|
/* align_mem :
|
||||||
This macro is used to align an offset to point to a 32b value. It is used in the Matrix algorithm to initialize the input memory blocks.
|
This macro is used to align an offset to point to a 32b value. It is
|
||||||
|
used in the Matrix algorithm to initialize the input memory blocks.
|
||||||
*/
|
*/
|
||||||
#define align_mem(x) (void *)(4 + (((ee_ptr_int)(x) - 1) & ~3))
|
#define align_mem(x) (void *)(4 + (((ee_ptr_int)(x)-1) & ~3))
|
||||||
|
|
||||||
/* Configuration : SEED_METHOD
|
/* Configuration : SEED_METHOD
|
||||||
Defines method to get seed values that cannot be computed at compile time.
|
Defines method to get seed values that cannot be computed at compile
|
||||||
|
time.
|
||||||
Valid values :
|
|
||||||
SEED_ARG - from command line.
|
Valid values :
|
||||||
SEED_FUNC - from a system function.
|
SEED_ARG - from command line.
|
||||||
SEED_VOLATILE - from volatile variables.
|
SEED_FUNC - from a system function.
|
||||||
|
SEED_VOLATILE - from volatile variables.
|
||||||
*/
|
*/
|
||||||
#ifndef SEED_METHOD
|
#ifndef SEED_METHOD
|
||||||
#define SEED_METHOD SEED_VOLATILE
|
#define SEED_METHOD SEED_VOLATILE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Configuration : MEM_METHOD
|
/* Configuration : MEM_METHOD
|
||||||
Defines method to get a block of memry.
|
Defines method to get a block of memry.
|
||||||
|
|
||||||
Valid values :
|
Valid values :
|
||||||
MEM_MALLOC - for platforms that implement malloc and have malloc.h.
|
MEM_MALLOC - for platforms that implement malloc and have malloc.h.
|
||||||
MEM_STATIC - to use a static memory array.
|
MEM_STATIC - to use a static memory array.
|
||||||
MEM_STACK - to allocate the data block on the stack (NYI).
|
MEM_STACK - to allocate the data block on the stack (NYI).
|
||||||
*/
|
*/
|
||||||
#ifndef MEM_METHOD
|
#ifndef MEM_METHOD
|
||||||
#define MEM_METHOD MEM_STACK
|
#define MEM_METHOD MEM_STACK
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Configuration : MULTITHREAD
|
/* Configuration : MULTITHREAD
|
||||||
Define for parallel execution
|
Define for parallel execution
|
||||||
|
|
||||||
Valid values :
|
Valid values :
|
||||||
1 - only one context (default).
|
1 - only one context (default).
|
||||||
N>1 - will execute N copies in parallel.
|
N>1 - will execute N copies in parallel.
|
||||||
|
|
||||||
Note :
|
Note :
|
||||||
If this flag is defined to more then 1, an implementation for launching parallel contexts must be defined.
|
If this flag is defined to more then 1, an implementation for launching
|
||||||
|
parallel contexts must be defined.
|
||||||
Two sample implementations are provided. Use <USE_PTHREAD> or <USE_FORK> to enable them.
|
|
||||||
|
Two sample implementations are provided. Use <USE_PTHREAD> or <USE_FORK>
|
||||||
It is valid to have a different implementation of <core_start_parallel> and <core_end_parallel> in <core_portme.c>,
|
to enable them.
|
||||||
to fit a particular architecture.
|
|
||||||
|
It is valid to have a different implementation of <core_start_parallel>
|
||||||
|
and <core_end_parallel> in <core_portme.c>, to fit a particular architecture.
|
||||||
*/
|
*/
|
||||||
#ifndef MULTITHREAD
|
#ifndef MULTITHREAD
|
||||||
#define MULTITHREAD 1
|
#define MULTITHREAD 1
|
||||||
#define USE_PTHREAD 0
|
#define USE_PTHREAD 0
|
||||||
#define USE_FORK 0
|
#define USE_FORK 0
|
||||||
#define USE_SOCKET 0
|
#define USE_SOCKET 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Configuration : MAIN_HAS_NOARGC
|
/* Configuration : MAIN_HAS_NOARGC
|
||||||
Needed if platform does not support getting arguments to main.
|
Needed if platform does not support getting arguments to main.
|
||||||
|
|
||||||
Valid values :
|
Valid values :
|
||||||
0 - argc/argv to main is supported
|
0 - argc/argv to main is supported
|
||||||
1 - argc/argv to main is not supported
|
1 - argc/argv to main is not supported
|
||||||
|
|
||||||
Note :
|
Note :
|
||||||
This flag only matters if MULTITHREAD has been defined to a value greater then 1.
|
This flag only matters if MULTITHREAD has been defined to a value
|
||||||
|
greater then 1.
|
||||||
*/
|
*/
|
||||||
#ifndef MAIN_HAS_NOARGC
|
#ifndef MAIN_HAS_NOARGC
|
||||||
#define MAIN_HAS_NOARGC 0
|
#define MAIN_HAS_NOARGC 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Configuration : MAIN_HAS_NORETURN
|
/* Configuration : MAIN_HAS_NORETURN
|
||||||
Needed if platform does not support returning a value from main.
|
Needed if platform does not support returning a value from main.
|
||||||
|
|
||||||
Valid values :
|
Valid values :
|
||||||
0 - main returns an int, and return value will be 0.
|
0 - main returns an int, and return value will be 0.
|
||||||
1 - platform does not support returning a value from main
|
1 - platform does not support returning a value from main
|
||||||
*/
|
*/
|
||||||
#ifndef MAIN_HAS_NORETURN
|
#ifndef MAIN_HAS_NORETURN
|
||||||
#define MAIN_HAS_NORETURN 0
|
#define MAIN_HAS_NORETURN 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Variable : default_num_contexts
|
/* Variable : default_num_contexts
|
||||||
Not used for this simple port, must cintain the value 1.
|
Not used for this simple port, must cintain the value 1.
|
||||||
*/
|
*/
|
||||||
extern ee_u32 default_num_contexts;
|
extern ee_u32 default_num_contexts;
|
||||||
|
|
||||||
typedef struct CORE_PORTABLE_S {
|
typedef struct CORE_PORTABLE_S
|
||||||
ee_u8 portable_id;
|
{
|
||||||
|
ee_u8 portable_id;
|
||||||
} core_portable;
|
} core_portable;
|
||||||
|
|
||||||
/* target specific init/fini */
|
/* target specific init/fini */
|
||||||
void portable_init(core_portable *p, int *argc, char *argv[]);
|
void portable_init(core_portable *p, int *argc, char *argv[]);
|
||||||
void portable_fini(core_portable *p);
|
void portable_fini(core_portable *p);
|
||||||
|
|
||||||
#if !defined(PROFILE_RUN) && !defined(PERFORMANCE_RUN) && !defined(VALIDATION_RUN)
|
#if !defined(PROFILE_RUN) && !defined(PERFORMANCE_RUN) \
|
||||||
#if (TOTAL_DATA_SIZE==1200)
|
&& !defined(VALIDATION_RUN)
|
||||||
|
#if (TOTAL_DATA_SIZE == 1200)
|
||||||
#define PROFILE_RUN 1
|
#define PROFILE_RUN 1
|
||||||
#elif (TOTAL_DATA_SIZE==2000)
|
#elif (TOTAL_DATA_SIZE == 2000)
|
||||||
#define PERFORMANCE_RUN 1
|
#define PERFORMANCE_RUN 1
|
||||||
#else
|
#else
|
||||||
#define VALIDATION_RUN 1
|
#define VALIDATION_RUN 1
|
||||||
|
Loading…
Reference in New Issue
Block a user