229 lines
5.8 KiB
C
229 lines
5.8 KiB
C
/*
|
|
|
|
This program is part of the TACLeBench benchmark suite.
|
|
Version V 2.0
|
|
|
|
Name: st
|
|
|
|
Author: unknown
|
|
|
|
Function: st is a statistics program.
|
|
This program computes for two arrays of numbers the sum, the mean,
|
|
the variance, and standard deviation. It then determines the
|
|
correlation coefficient between the two arrays.
|
|
|
|
Source: MRTC
|
|
http://www.mrtc.mdh.se/projects/wcet/wcet_bench/st/st.c
|
|
|
|
Changes: No major functional changes.
|
|
|
|
License: May be used, modified, and re-distributed freely
|
|
|
|
*/
|
|
|
|
/*
|
|
Forward declaration of functions
|
|
*/
|
|
|
|
// Wasm loop bounds
|
|
|
|
|
|
|
|
|
|
__attribute__((import_module("__pragma"), import_name("loopbound"))) extern void
|
|
__pragma_loopbound(unsigned int min_bound, unsigned int max_bound);
|
|
|
|
__attribute__((always_inline)) static inline void st_initSeed(void);
|
|
__attribute__((always_inline)) static inline long st_randomInteger();
|
|
__attribute__((always_inline)) static inline void st_initialize(float *);
|
|
__attribute__((always_inline)) static inline void st_init(void);
|
|
__attribute__((always_inline)) static inline int st_return(void);
|
|
__attribute__((always_inline)) static inline float st_fabs(float);
|
|
__attribute__((always_inline)) static inline float st_sqrtf(float);
|
|
__attribute__((always_inline)) static inline float st_square(float);
|
|
__attribute__((always_inline)) static inline void
|
|
st_calc_Sum_Mean(float *, float *, float *);
|
|
__attribute__((always_inline)) static inline void
|
|
st_calc_Var_Stddev(float *, float, float *, float *);
|
|
__attribute__((always_inline)) static inline void
|
|
st_calc_LinCorrCoef(float *, float *, float, float, float *);
|
|
__attribute__((noinline)) __attribute__((export_name("entrypoint")))
|
|
__attribute__((noinline)) __attribute__((export_name("entrypoint"))) void
|
|
st_main(void);
|
|
__attribute__((noinline)) __attribute__((export_name("main")))
|
|
__attribute__((noinline)) __attribute__((export_name("main"))) int
|
|
main(void);
|
|
|
|
/*
|
|
Declaration of global variables
|
|
*/
|
|
|
|
volatile int st_seed;
|
|
float st_arrayA[1000], st_arrayB[1000];
|
|
float st_sumA, st_sumB;
|
|
float st_meanA, st_meanB, st_varA, st_varB, st_stddevA, st_stddevB, st_coef;
|
|
|
|
/*
|
|
Initialization- and return-value-related functions
|
|
*/
|
|
|
|
/*
|
|
st_initSeed initializes the seed used in the "random" number generator.
|
|
*/
|
|
__attribute__((always_inline)) static inline void
|
|
st_initSeed() {
|
|
st_seed = 0;
|
|
}
|
|
|
|
/*
|
|
st_RandomInteger generates random integers between 0 and 8094.
|
|
*/
|
|
__attribute__((always_inline)) static inline long
|
|
st_randomInteger() {
|
|
st_seed = ((st_seed * 133) + 81) % 8095;
|
|
return (st_seed);
|
|
}
|
|
|
|
__attribute__((always_inline)) static inline void
|
|
st_initialize(float *array) {
|
|
register int i;
|
|
|
|
__pragma_loopbound(1000, 1000);
|
|
for (i = 0; i < 1000; i++)
|
|
array[i] = i + st_randomInteger();
|
|
}
|
|
|
|
__attribute__((always_inline)) static inline void
|
|
st_init() {
|
|
st_initSeed();
|
|
st_initialize(st_arrayA);
|
|
st_initialize(st_arrayB);
|
|
}
|
|
|
|
__attribute__((always_inline)) static inline int
|
|
st_return() {
|
|
float checksum = st_meanA + st_meanB + st_stddevA + st_stddevB + st_coef;
|
|
/* allow rounding errors for the checksum */
|
|
checksum -= 13695.986328;
|
|
return ((checksum < 0.000001 && checksum > -0.000001) ? 0 : -1);
|
|
}
|
|
|
|
/*
|
|
Arithmetic math functions
|
|
*/
|
|
|
|
__attribute__((always_inline)) static inline float
|
|
st_fabs(float n) {
|
|
float f;
|
|
|
|
if (n >= 0)
|
|
f = n;
|
|
else
|
|
f = -n;
|
|
|
|
return (f);
|
|
}
|
|
|
|
__attribute__((always_inline)) static inline float
|
|
st_sqrtf(float val) {
|
|
float x = val / 10;
|
|
float dx;
|
|
float diff;
|
|
float min_tol = 0.00001f;
|
|
|
|
int i, flag = 0;
|
|
|
|
if (val == 0)
|
|
x = 0;
|
|
else {
|
|
__pragma_loopbound(19, 19);
|
|
for (i = 1; i < 20; i++) {
|
|
if (!flag) {
|
|
dx = (val - (x * x)) / (2.0f * x);
|
|
x = x + dx;
|
|
diff = val - (x * x);
|
|
|
|
if (st_fabs(diff) <= min_tol)
|
|
flag = 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
return (x);
|
|
}
|
|
|
|
__attribute__((always_inline)) static inline float
|
|
st_square(float x) {
|
|
return (x * x);
|
|
}
|
|
|
|
/*
|
|
Algorithm core functions
|
|
*/
|
|
|
|
__attribute__((always_inline)) static inline void
|
|
st_calc_Sum_Mean(float *array, float *sum, float *mean) {
|
|
int i;
|
|
|
|
*sum = 0;
|
|
|
|
__pragma_loopbound(1000, 1000);
|
|
for (i = 0; i < 1000; i++)
|
|
*sum += array[i];
|
|
*mean = *sum / 1000;
|
|
}
|
|
|
|
__attribute__((always_inline)) static inline void
|
|
st_calc_Var_Stddev(float *array, float mean, float *var, float *stddev) {
|
|
int i;
|
|
float diffs = 0.0f;
|
|
|
|
__pragma_loopbound(1000, 1000);
|
|
for (i = 0; i < 1000; i++)
|
|
diffs += st_square(array[i] - mean);
|
|
|
|
*var = diffs / 1000;
|
|
*stddev = st_sqrtf(*var);
|
|
}
|
|
|
|
__attribute__((always_inline)) static inline void
|
|
st_calc_LinCorrCoef(float *arrayA, float *arrayB, float meanA, float meanB,
|
|
float *coef) {
|
|
int i;
|
|
float numerator = 0.0f, Aterm = 0.0f, Bterm = 0.0f;
|
|
|
|
__pragma_loopbound(1000, 1000);
|
|
for (i = 0; i < 1000; i++) {
|
|
numerator += (arrayA[i] - meanA) * (arrayB[i] - meanB);
|
|
Aterm += st_square(arrayA[i] - meanA);
|
|
Bterm += st_square(arrayB[i] - meanB);
|
|
}
|
|
|
|
*coef = numerator / (st_sqrtf(Aterm) * st_sqrtf(Bterm));
|
|
}
|
|
|
|
/*
|
|
Main functions
|
|
*/
|
|
|
|
__attribute__((noinline)) __attribute__((export_name("entrypoint")))
|
|
__attribute__((noinline)) __attribute__((export_name("entrypoint"))) void
|
|
st_main(void) {
|
|
st_calc_Sum_Mean(st_arrayA, &st_sumA, &st_meanA);
|
|
st_calc_Var_Stddev(st_arrayA, st_meanA, &st_varA, &st_stddevA);
|
|
|
|
st_calc_Sum_Mean(st_arrayB, &st_sumB, &st_meanB);
|
|
st_calc_Var_Stddev(st_arrayB, st_meanB, &st_varB, &st_stddevB);
|
|
|
|
st_calc_LinCorrCoef(st_arrayA, st_arrayB, st_meanA, st_meanB, &st_coef);
|
|
}
|
|
|
|
__attribute__((noinline)) __attribute__((export_name("main")))
|
|
__attribute__((noinline)) __attribute__((export_name("main"))) int
|
|
main(void) {
|
|
st_init();
|
|
st_main();
|
|
|
|
return (st_return());
|
|
}
|