DDA: don't queue up heater waits.

Not queuing up waits for the heaters in the movement queue removes
some code in performance critical paths. What a luck we just
implemented an alternative M116 functionality with the previous
commit :-)

Performance of the slowest step is decreased a nice 29 clock
cycles and binary size decreased by a whoppy 472 bytes. That's
still 210 bytes less than before implementing the alternative
heater wait.

Best of all, average step time is down some 21 clock cycles, too,
so we increased general stepping performance by no less than 5%.

  ATmega sizes               '168   '328(P)   '644(P)     '1280
  Program:  19436 bytes      136%       64%       31%       16%
     Data:   2177 bytes      213%      107%       54%       27%
   EEPROM:     32 bytes        4%        2%        2%        1%

  short-moves.gcode statistics:
  LED on occurences: 888.
  LED on time minimum: 259 clock cycles.
  LED on time maximum: 429 clock cycles.
  LED on time average: 263.491 clock cycles.

  smooth-curves.gcode statistics:
  LED on occurences: 23648.
  LED on time minimum: 251 clock cycles.
  LED on time maximum: 472 clock cycles.
  LED on time average: 286.259 clock cycles.

  triangle-odd.gcode statistics:
  LED on occurences: 1636.
  LED on time minimum: 251 clock cycles.
  LED on time maximum: 429 clock cycles.
  LED on time average: 276.616 clock cycles.
This commit is contained in:
Markus Hitter 2016-11-22 01:21:55 +01:00
parent fb49aef14d
commit fc70e00ca2
4 changed files with 10 additions and 42 deletions

5
dda.c
View File

@ -159,13 +159,10 @@ void dda_create(DDA *dda, const TARGET *target) {
static uint8_t idcnt = 0;
static DDA* prev_dda = NULL;
if ((prev_dda && prev_dda->done) || dda->waitfor_temp)
if (prev_dda && prev_dda->done)
prev_dda = NULL;
#endif
if (dda->waitfor_temp)
return;
// We end at the passed target.
memcpy(&(dda->endpoint), target, sizeof(TARGET));

5
dda.h
View File

@ -85,15 +85,12 @@ typedef struct {
struct {
// status fields
uint8_t nullmove :1; ///< bool: no axes move, maybe we wait for temperatures or change speed
uint8_t live :1; ///< bool: this DDA is running and still has steps to do
volatile uint8_t live :1; ///< bool: this DDA is running and still has steps to do
uint8_t done :1; ///< bool: this DDA is done.
#ifdef ACCELERATION_REPRAP
uint8_t accel :1; ///< bool: speed changes during this move, run accel code
#endif
// wait for temperature to stabilise flag
uint8_t waitfor_temp :1; ///< bool: wait for temperatures to reach their set values
// directions
// As we have muldiv() now, overflows became much less an issue and
// it's likely time to get rid of these flags and use int instead of

View File

@ -63,7 +63,7 @@ DDA *queue_current_movement() {
ATOMIC_START
current = &movebuffer[mb_tail];
if ( ! current->live || current->waitfor_temp)
if ( ! current->live)
current = NULL;
ATOMIC_END
@ -76,27 +76,15 @@ DDA *queue_current_movement() {
// -------------------------------------------------------
/// Take a step or go to the next move.
void queue_step() {
// do our next step
DDA* current_movebuffer = &movebuffer[mb_tail];
if (current_movebuffer->live) {
if (current_movebuffer->waitfor_temp) {
timer_set(HEATER_WAIT_TIMEOUT, 0);
if (temp_achieved()) {
current_movebuffer->live = current_movebuffer->done = 0;
serial_writestr_P(PSTR("Temp achieved\n"));
}
else {
temp_print(TEMP_SENSOR_none);
}
}
else {
dda_step(current_movebuffer);
}
if (movebuffer[mb_tail].live) {
dda_step(&movebuffer[mb_tail]);
}
// Start the next move if this one is done.
if (current_movebuffer->live == 0)
if ( ! movebuffer[mb_tail].live) {
next_move();
}
}
/// add a move to the movebuffer
@ -115,14 +103,8 @@ void enqueue_home(TARGET *t, uint8_t endstop_check, uint8_t endstop_stop_cond) {
// dda->live, dda->done and dda->wait_for_temp.
new_movebuffer->allflags = 0;
if (t != NULL) {
new_movebuffer->endstop_check = endstop_check;
new_movebuffer->endstop_stop_cond = endstop_stop_cond;
}
else {
// it's a wait for temp
new_movebuffer->waitfor_temp = 1;
}
new_movebuffer->endstop_check = endstop_check;
new_movebuffer->endstop_stop_cond = endstop_stop_cond;
dda_create(new_movebuffer, t);
/**
@ -170,16 +152,9 @@ void next_move() {
// interrupt routine.
mb_tail = MB_NEXT(mb_tail);
if (movebuffer[mb_tail].waitfor_temp) {
serial_writestr_P(PSTR("Waiting for target temp\n"));
movebuffer[mb_tail].live = 1;
timer_set(HEATER_WAIT_TIMEOUT, 0);
}
else {
dda_start(&movebuffer[mb_tail]);
}
}
}
/// DEBUG - print queue.
/// Qt/hs format, t is tail, h is head, s is F/full, E/empty or neither

View File

@ -5,7 +5,6 @@
#include "dda.h"
#include "timer.h"
#define HEATER_WAIT_TIMEOUT 1000 MS
/*
variables