|
@@ -1,5 +1,7 @@
|
|
|
#include <stdio.h>
|
|
#include <stdio.h>
|
|
|
#include <string.h>
|
|
#include <string.h>
|
|
|
|
|
+#include <stdint.h>
|
|
|
|
|
+#include <math.h>
|
|
|
|
|
|
|
|
#include "ImC/imc_kernel.h"
|
|
#include "ImC/imc_kernel.h"
|
|
|
#include "ImC/imc_extension.h"
|
|
#include "ImC/imc_extension.h"
|
|
@@ -85,7 +87,9 @@ int pass_due_to_low_energy;
|
|
|
void imc_recover_estimations()
|
|
void imc_recover_estimations()
|
|
|
{
|
|
{
|
|
|
#if(imcLOOP_OPT_DEBUG && imcLOOP_OPT_DEBUG_VERBOSE)
|
|
#if(imcLOOP_OPT_DEBUG && imcLOOP_OPT_DEBUG_VERBOSE)
|
|
|
|
|
+ portDISABLE_INTERRUPTS();
|
|
|
printf("(DEBUG) recover estimation table from buffer %d\r\n", latest_buffer_index);
|
|
printf("(DEBUG) recover estimation table from buffer %d\r\n", latest_buffer_index);
|
|
|
|
|
+ portENABLE_INTERRUPTS();
|
|
|
#endif
|
|
#endif
|
|
|
memcpy(loop_pass_estimation, estimation_backup[latest_buffer_index], sizeof(float) * imcMAX_LOOP_IDS);
|
|
memcpy(loop_pass_estimation, estimation_backup[latest_buffer_index], sizeof(float) * imcMAX_LOOP_IDS);
|
|
|
__DSB();
|
|
__DSB();
|
|
@@ -94,7 +98,9 @@ int pass_due_to_low_energy;
|
|
|
void imc_backup_estimations() {
|
|
void imc_backup_estimations() {
|
|
|
int nextBufferIndex = latest_buffer_index == 0 ? 1 : 0;
|
|
int nextBufferIndex = latest_buffer_index == 0 ? 1 : 0;
|
|
|
#if(imcLOOP_OPT_DEBUG && imcLOOP_OPT_DEBUG_VERBOSE)
|
|
#if(imcLOOP_OPT_DEBUG && imcLOOP_OPT_DEBUG_VERBOSE)
|
|
|
|
|
+ portDISABLE_INTERRUPTS();
|
|
|
printf("(DEBUG) backup estimation table to buffer %d\r\n", nextBufferIndex);
|
|
printf("(DEBUG) backup estimation table to buffer %d\r\n", nextBufferIndex);
|
|
|
|
|
+ portENABLE_INTERRUPTS();
|
|
|
#endif
|
|
#endif
|
|
|
memcpy(estimation_backup[nextBufferIndex], loop_pass_estimation, sizeof(float) * imcMAX_LOOP_IDS);
|
|
memcpy(estimation_backup[nextBufferIndex], loop_pass_estimation, sizeof(float) * imcMAX_LOOP_IDS);
|
|
|
latest_buffer_index = nextBufferIndex;
|
|
latest_buffer_index = nextBufferIndex;
|
|
@@ -116,10 +122,12 @@ void imc_init_energy_estimation() {
|
|
|
|
|
|
|
|
if(!imc_energy_estimation_initialized) {
|
|
if(!imc_energy_estimation_initialized) {
|
|
|
#if(imcLOOP_OPT_DEBUG)
|
|
#if(imcLOOP_OPT_DEBUG)
|
|
|
|
|
+ portDISABLE_INTERRUPTS();
|
|
|
printf("(DEBUG) initialize estimation table\r\n");
|
|
printf("(DEBUG) initialize estimation table\r\n");
|
|
|
|
|
+ portENABLE_INTERRUPTS();
|
|
|
#endif
|
|
#endif
|
|
|
for(int i=0; i<imcMAX_LOOP_IDS; i++) {
|
|
for(int i=0; i<imcMAX_LOOP_IDS; i++) {
|
|
|
- loop_pass_estimation[i] = 2;
|
|
|
|
|
|
|
+ loop_pass_estimation[i] = 3;
|
|
|
}
|
|
}
|
|
|
latest_buffer_index = 0;
|
|
latest_buffer_index = 0;
|
|
|
#if(imcPRINT_STATS)
|
|
#if(imcPRINT_STATS)
|
|
@@ -170,11 +178,16 @@ void update_estimation(int loop_id, int counter, int current_energy, int energy_
|
|
|
float current_estimation = (float)loop_pass_estimation[loop_id];
|
|
float current_estimation = (float)loop_pass_estimation[loop_id];
|
|
|
if(current_estimation > 1e6) return;
|
|
if(current_estimation > 1e6) return;
|
|
|
const float error_margin = imcENERGY_TOTAL * 0.03;
|
|
const float error_margin = imcENERGY_TOTAL * 0.03;
|
|
|
|
|
+ // const float error_margin = imcENERGY_TOTAL * 0;
|
|
|
float max_consumed = energy_at_start + error_margin - (current_energy - error_margin);
|
|
float max_consumed = energy_at_start + error_margin - (current_energy - error_margin);
|
|
|
float min_consumed = energy_at_start - error_margin - (current_energy + error_margin);
|
|
float min_consumed = energy_at_start - error_margin - (current_energy + error_margin);
|
|
|
|
|
+ // if(max_consumed <= 0) max_consumed = 1e-3;
|
|
|
|
|
+ // if(min_consumed <= 0) {
|
|
|
|
|
+ // min_consumed = 1e-3;
|
|
|
|
|
+ // }
|
|
|
if(max_consumed <= 0) max_consumed = 1e-3;
|
|
if(max_consumed <= 0) max_consumed = 1e-3;
|
|
|
if(min_consumed <= 0) {
|
|
if(min_consumed <= 0) {
|
|
|
- min_consumed = 1e-3;
|
|
|
|
|
|
|
+ min_consumed = 1;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
float measured_min = ((float)(imcENERGY_TOTAL)) / max_consumed * counter;
|
|
float measured_min = ((float)(imcENERGY_TOTAL)) / max_consumed * counter;
|
|
@@ -207,12 +220,27 @@ void update_estimation(int loop_id, int counter, int current_energy, int energy_
|
|
|
new_estimation = current_estimation * factor;
|
|
new_estimation = current_estimation * factor;
|
|
|
loop_pass_estimation[loop_id] = new_estimation;
|
|
loop_pass_estimation[loop_id] = new_estimation;
|
|
|
}
|
|
}
|
|
|
- else return;
|
|
|
|
|
|
|
+ else {
|
|
|
|
|
+ #if(imcLOOP_OPT_DEBUG)
|
|
|
|
|
+ portDISABLE_INTERRUPTS();
|
|
|
|
|
+ printf("(DEBUG) Estimation not updated; loop_id:%d, counter:%d, measured_min: %f, measured_max: %f, current_estimation: %f\r\n",
|
|
|
|
|
+ loop_id, counter, measured_min, measured_max, current_estimation);
|
|
|
|
|
+ portENABLE_INTERRUPTS();
|
|
|
|
|
+ #endif
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const int max_estimation = 1000000;
|
|
|
|
|
+ if(new_estimation > max_estimation) {
|
|
|
|
|
+ new_estimation = max_estimation;
|
|
|
|
|
+ loop_pass_estimation[loop_id] = max_estimation;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
#if(imcLOOP_OPT_DEBUG)
|
|
#if(imcLOOP_OPT_DEBUG)
|
|
|
portDISABLE_INTERRUPTS();
|
|
portDISABLE_INTERRUPTS();
|
|
|
printf("(DEBUG) estimation for loop %d is updated to %f\r\n", loop_id, new_estimation);
|
|
printf("(DEBUG) estimation for loop %d is updated to %f\r\n", loop_id, new_estimation);
|
|
|
portENABLE_INTERRUPTS();
|
|
portENABLE_INTERRUPTS();
|
|
|
|
|
+
|
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
imc_backup_estimations();
|
|
imc_backup_estimations();
|
|
@@ -263,7 +291,9 @@ void __imc_finish_loop_skipping() {
|
|
|
// int volt = measure_voltage(ADC_HANDLER_SBC, EPS_CAP_ID_SBC);
|
|
// int volt = measure_voltage(ADC_HANDLER_SBC, EPS_CAP_ID_SBC);
|
|
|
// int energy = volt*volt - imcCAP_VOL_LOW*imcCAP_VOL_LOW;
|
|
// int energy = volt*volt - imcCAP_VOL_LOW*imcCAP_VOL_LOW;
|
|
|
#if(imcLOOP_OPT_DEBUG)
|
|
#if(imcLOOP_OPT_DEBUG)
|
|
|
- printf("(DEBUG) loop %d is not perfectly skipped\r\n", loop_id);
|
|
|
|
|
|
|
+ portDISABLE_INTERRUPTS();
|
|
|
|
|
+ // printf("(DEBUG) loop %d is not perfectly skipped\r\n", loop_id);
|
|
|
|
|
+ portENABLE_INTERRUPTS();
|
|
|
#endif
|
|
#endif
|
|
|
int energy = get_current_energy();
|
|
int energy = get_current_energy();
|
|
|
int energy_consumed = imc_energy_at_start - energy;
|
|
int energy_consumed = imc_energy_at_start - energy;
|
|
@@ -272,46 +302,6 @@ void __imc_finish_loop_skipping() {
|
|
|
if(!last_skip_is_zero) {
|
|
if(!last_skip_is_zero) {
|
|
|
update_estimation(loop_id, last_loop_skip_count, energy, imc_energy_at_start);
|
|
update_estimation(loop_id, last_loop_skip_count, energy, imc_energy_at_start);
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- /*
|
|
|
|
|
- float possible_iterations_estimated = 0;
|
|
|
|
|
- int underestimated = 0;
|
|
|
|
|
- if(!last_skip_is_zero) {
|
|
|
|
|
- float energy_per_iteration = (float)energy_consumed / last_loop_skip_count;
|
|
|
|
|
- possible_iterations_estimated = (float)energy / energy_per_iteration;
|
|
|
|
|
- underestimated = possible_iterations_estimated > 3;
|
|
|
|
|
- }
|
|
|
|
|
- if(!last_skip_is_zero && underestimated) {
|
|
|
|
|
- int current_estimation = loop_pass_estimation[loop_id];
|
|
|
|
|
- // double inc_factor = 2.5;
|
|
|
|
|
- double inc_factor = possible_iterations_estimated > 3 ? 3 : possible_iterations_estimated;
|
|
|
|
|
- if (current_estimation * inc_factor > (double)INT32_MAX)
|
|
|
|
|
- {
|
|
|
|
|
- current_estimation = INT32_MAX/2-1;
|
|
|
|
|
- }
|
|
|
|
|
- else
|
|
|
|
|
- {
|
|
|
|
|
- current_estimation = (int)(current_estimation * inc_factor);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if (current_estimation < 1) {
|
|
|
|
|
- current_estimation = 1;
|
|
|
|
|
- }
|
|
|
|
|
- loop_pass_estimation[loop_id] = current_estimation;
|
|
|
|
|
- #if (imcLOOP_OPT_DEBUG)
|
|
|
|
|
- portDISABLE_INTERRUPTS();
|
|
|
|
|
- printf("(DEBUG) estimation for loop %d is updated to %d\r\n", loop_id, current_estimation);
|
|
|
|
|
- portENABLE_INTERRUPTS();
|
|
|
|
|
- #endif
|
|
|
|
|
- imc_backup_estimations();
|
|
|
|
|
- } else {
|
|
|
|
|
- #if (imcLOOP_OPT_DEBUG)
|
|
|
|
|
- portDISABLE_INTERRUPTS();
|
|
|
|
|
- printf("(DEBUG) estimation for loop %d is not updated (%d)\r\n", loop_id, loop_pass_estimation[loop_id]);
|
|
|
|
|
- portENABLE_INTERRUPTS();
|
|
|
|
|
- #endif
|
|
|
|
|
- }
|
|
|
|
|
- */
|
|
|
|
|
}
|
|
}
|
|
|
imc_is_passing_loops_backup = -1;
|
|
imc_is_passing_loops_backup = -1;
|
|
|
imc_is_passing_loops = -1;
|
|
imc_is_passing_loops = -1;
|
|
@@ -342,7 +332,9 @@ int __imc_get_loop_pass_count(int loop_id) {
|
|
|
imc_energy_at_start = energy;
|
|
imc_energy_at_start = energy;
|
|
|
|
|
|
|
|
#if(imcLOOP_OPT_DEBUG && imcLOOP_OPT_DEBUG_VERBOSE)
|
|
#if(imcLOOP_OPT_DEBUG && imcLOOP_OPT_DEBUG_VERBOSE)
|
|
|
- printf("(DEBUG) ratio: %d\r\n", ratio);
|
|
|
|
|
|
|
+ portDISABLE_INTERRUPTS();
|
|
|
|
|
+ printf("(DEBUG) loopId: %d, ratio: %d\r\n", loop_id, ratio);
|
|
|
|
|
+ portENABLE_INTERRUPTS();
|
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
float current_estimation = loop_pass_estimation[loop_id];
|
|
float current_estimation = loop_pass_estimation[loop_id];
|
|
@@ -355,17 +347,37 @@ int __imc_get_loop_pass_count(int loop_id) {
|
|
|
imc_is_passing_loops_backup = -1;
|
|
imc_is_passing_loops_backup = -1;
|
|
|
// imc_sbc_power_off();
|
|
// imc_sbc_power_off();
|
|
|
#if(imcLOOP_OPT_DEBUG && imcLOOP_OPT_DEBUG_VERBOSE)
|
|
#if(imcLOOP_OPT_DEBUG && imcLOOP_OPT_DEBUG_VERBOSE)
|
|
|
|
|
+ portDISABLE_INTERRUPTS();
|
|
|
printf("(DEBUG) ratio: %d\r\n", ratio);
|
|
printf("(DEBUG) ratio: %d\r\n", ratio);
|
|
|
|
|
+ portENABLE_INTERRUPTS();
|
|
|
#endif
|
|
#endif
|
|
|
// while(1) { __ASM(" nop"); }
|
|
// while(1) { __ASM(" nop"); }
|
|
|
// printf("__imc_get_loop_pass_count(%d) called; %d returned\r\n", loop_id, last_loop_skip_count);
|
|
// printf("__imc_get_loop_pass_count(%d) called; %d returned\r\n", loop_id, last_loop_skip_count);
|
|
|
}
|
|
}
|
|
|
else {
|
|
else {
|
|
|
double r = (double)(ratio) / 100.0;
|
|
double r = (double)(ratio) / 100.0;
|
|
|
- last_loop_skip_count = (int)((double)current_estimation * r);
|
|
|
|
|
|
|
+ double target_skip_count = current_estimation * r;
|
|
|
|
|
+ #if(imcLOOP_OPT_DEBUG && imcLOOP_OPT_DEBUG_VERBOSE)
|
|
|
|
|
+ portDISABLE_INTERRUPTS();
|
|
|
|
|
+ printf("(DEBUG) loop_id:%d, current estimation: %f, target_skip_count: %f, r: %f\r\n", loop_id, current_estimation, target_skip_count, r);
|
|
|
|
|
+ portENABLE_INTERRUPTS();
|
|
|
|
|
+ #endif
|
|
|
|
|
+ const int max_skip_count = 10000;
|
|
|
|
|
+ // if(target_skip_count > max_skip_count) {
|
|
|
|
|
+ // last_loop_skip_count = max_skip_count;
|
|
|
|
|
+ // } else {
|
|
|
|
|
+ // last_loop_skip_count = (int)target_skip_count;
|
|
|
|
|
+ // }
|
|
|
|
|
+ if (isnan(target_skip_count) || target_skip_count < 1.0) {
|
|
|
|
|
+ last_loop_skip_count = 0;
|
|
|
|
|
+ } else if (target_skip_count > max_skip_count) {
|
|
|
|
|
+ last_loop_skip_count = max_skip_count;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ last_loop_skip_count = (int)target_skip_count;
|
|
|
|
|
+ }
|
|
|
// last_loop_skip_count = loop_pass_estimation[loop_id] * ((double)(ratio) / 100.0);
|
|
// last_loop_skip_count = loop_pass_estimation[loop_id] * ((double)(ratio) / 100.0);
|
|
|
}
|
|
}
|
|
|
- // printf("loopId: %d, volt: %d, energy: %d, total: %d, ratio: %d, est:%d, count:%d\r\n", loop_id, volt, energy, imcENERGY_TOTAL, ratio, current_estimation, last_loop_skip_count);
|
|
|
|
|
|
|
+ // printf("loopId: %d, volt: %d, energy: %d, total: %d, ratio: %d, est:%f, count:%d\r\n", loop_id, volt, energy, imcENERGY_TOTAL, ratio, current_estimation, last_loop_skip_count);
|
|
|
#if (imcPRINT_LATENCY_OVERHEAD)
|
|
#if (imcPRINT_LATENCY_OVERHEAD)
|
|
|
unsigned int end_tick = DWT->CYCCNT;
|
|
unsigned int end_tick = DWT->CYCCNT;
|
|
|
imc_ticks_getCSC += end_tick - start_tick;
|
|
imc_ticks_getCSC += end_tick - start_tick;
|