#include #include typedef struct { unsigned int d1; // high to low: d1 = 3 unsigned int d3; // low to high: d3 = 3 unsigned int s1; // high to off: s1 = 30 unsigned int s3; // off to high: s3 = 3 unsigned int s4; // high: s4 = 4 // s3+s4 = time to refetch data from L2; } PARM; typedef enum {Active, Drowsy, Sleep} STATE; typedef struct { float opt_drowsy; float opt_sleep; float opt_hybrid; } OPT_ENERGY; float power(STATE s); float transition_energy(STATE from, STATE to); OPT_ENERGY * energy_saving(unsigned int *interval, unsigned int len, PARM parm) { OPT_ENERGY * opt_energy; unsigned int i, inflection_a, inflection_b; float te_active_drowsy, te_active_sleep, te_sleep_active, te_drowsy_active; // transition energies float saving; te_active_drowsy = transition_energy(Active, Drowsy); te_active_sleep = transition_energy(Active, Sleep); te_drowsy_active = transition_energy(Drowsy, Active); te_sleep_active = transition_energy(Sleep, Active); opt_energy = (OPT_ENERGY *) malloc(sizeof(OPT_ENERGY)); if (opt_energy == NULL) { printf("no enough memory to allocate\n"); exit(1); } opt_energy->opt_drowsy = 0.; opt_energy->opt_sleep = 0.; opt_energy->opt_hybrid = 0.; inflection_a = parm.d1 + parm.d3; inflection_b = (unsigned int)((te_active_sleep + te_sleep_active) - (te_active_drowsy + te_drowsy_active)) / power(Drowsy) + inflection_a; for (i = 0; i < len; i++) { if (interval[i] > inflection_b) { saving = power(Active) * interval[i] - te_active_sleep - te_sleep_active; opt_energy->opt_sleep += saving; opt_energy->opt_drowsy += power(Active) * interval[i] - te_active_drowsy - te_drowsy_active - power(Drowsy) * (interval[i] - inflection_a); } else if ( interval[i] > inflection_a ) { saving = power(Active) * interval[i] - te_active_drowsy - te_drowsy_active - power(Drowsy) * (interval[i] - inflection_a); opt_energy->opt_drowsy += saving; } else { saving = 0.; } opt_energy->opt_hybrid += saving; } return opt_energy; }