DDA: use bitmask to track active axes for faster dda_step().

In dda_step instead of checking our 32-bit-wide delta[n] value,
just check a single bit in an 8-bit field.  Should be a tad faster.
It does make the code larger, but also about 10% faster, I think.

Performance:

  ATmega sizes               '168   '328(P)   '644(P)     '1280
  Program:  19696 bytes      138%       65%       32%       16%
     Data:   2191 bytes      214%      107%       54%       27%
   EEPROM:     32 bytes        4%        2%        2%        1%

  short-moves.gcode statistics:
  LED on occurences: 888.
  LED on time minimum: 263 clock cycles.
  LED on time maximum: 532 clock cycles.
  LED on time average: 269.273 clock cycles.

  smooth-curves.gcode statistics:
  LED on occurences: 23648.
  LED on time minimum: 255 clock cycles.
  LED on time maximum: 571 clock cycles.
  LED on time average: 297.792 clock cycles.

  triangle-odd.gcode statistics:
  LED on occurences: 1636.
  LED on time minimum: 255 clock cycles.
  LED on time maximum: 522 clock cycles.
  LED on time average: 283.861 clock cycles.
This commit is contained in:
Phil Hord 2016-11-21 17:34:52 -08:00 committed by Markus Hitter
parent 1326db002f
commit 00a28cd502
2 changed files with 11 additions and 4 deletions

14
dda.c
View File

@ -187,6 +187,7 @@ void dda_create(DDA *dda, const TARGET *target) {
dda->id = idcnt++; dda->id = idcnt++;
#endif #endif
dda->active_axes = 0;
// Handle bot axes. They're subject to kinematics considerations. // Handle bot axes. They're subject to kinematics considerations.
code_axes_to_stepper_axes(&startpoint, target, delta_um, steps); code_axes_to_stepper_axes(&startpoint, target, delta_um, steps);
for (i = X; i < E; i++) { for (i = X; i < E; i++) {
@ -194,6 +195,8 @@ void dda_create(DDA *dda, const TARGET *target) {
delta_steps = steps[i] - startpoint_steps.axis[i]; delta_steps = steps[i] - startpoint_steps.axis[i];
dda->delta[i] = (uint32_t)labs(delta_steps); dda->delta[i] = (uint32_t)labs(delta_steps);
if (delta_steps)
dda->active_axes |= 1 << i;
startpoint_steps.axis[i] = steps[i]; startpoint_steps.axis[i] = steps[i];
set_direction(dda, i, delta_steps); set_direction(dda, i, delta_steps);
@ -255,6 +258,9 @@ void dda_create(DDA *dda, const TARGET *target) {
dda->e_direction = (target->axis[E] >= 0)?1:0; dda->e_direction = (target->axis[E] >= 0)?1:0;
} }
if (dda->delta[E])
dda->active_axes |= 1 << E;
if (DEBUG_DDA && (debug_flags & DEBUG_DDA)) if (DEBUG_DDA && (debug_flags & DEBUG_DDA))
sersendf_P(PSTR("[%ld,%ld,%ld,%ld]"), sersendf_P(PSTR("[%ld,%ld,%ld,%ld]"),
target->axis[X] - startpoint.axis[X], target->axis[Y] - startpoint.axis[Y], target->axis[X] - startpoint.axis[X], target->axis[Y] - startpoint.axis[Y],
@ -566,28 +572,28 @@ void dda_start(DDA *dda) {
void dda_step(DDA *dda) { void dda_step(DDA *dda) {
#if ! defined ACCELERATION_TEMPORAL #if ! defined ACCELERATION_TEMPORAL
if (dda->delta[X]) { if (dda->active_axes & (1 << X)) {
move_state.counter[X] -= dda->delta[X]; move_state.counter[X] -= dda->delta[X];
if (move_state.counter[X] < 0) { if (move_state.counter[X] < 0) {
x_step(); x_step();
move_state.counter[X] += dda->total_steps; move_state.counter[X] += dda->total_steps;
} }
} }
if (dda->delta[Y]) { if (dda->active_axes & (1 << Y)) {
move_state.counter[Y] -= dda->delta[Y]; move_state.counter[Y] -= dda->delta[Y];
if (move_state.counter[Y] < 0) { if (move_state.counter[Y] < 0) {
y_step(); y_step();
move_state.counter[Y] += dda->total_steps; move_state.counter[Y] += dda->total_steps;
} }
} }
if (dda->delta[Z]) { if (dda->active_axes & (1 << Z)) {
move_state.counter[Z] -= dda->delta[Z]; move_state.counter[Z] -= dda->delta[Z];
if (move_state.counter[Z] < 0) { if (move_state.counter[Z] < 0) {
z_step(); z_step();
move_state.counter[Z] += dda->total_steps; move_state.counter[Z] += dda->total_steps;
} }
} }
if (dda->delta[E]) { if (dda->active_axes & (1 << E)) {
move_state.counter[E] -= dda->delta[E]; move_state.counter[E] -= dda->delta[E];
if (move_state.counter[E] < 0) { if (move_state.counter[E] < 0) {
e_step(); e_step();

1
dda.h
View File

@ -156,6 +156,7 @@ typedef struct {
/// word boundaries only and fill smaller variables in between with gaps, /// word boundaries only and fill smaller variables in between with gaps,
/// so keep small variables grouped together to reduce the amount of these /// so keep small variables grouped together to reduce the amount of these
/// gaps. See e.g. NXP application note AN10963, page 10f. /// gaps. See e.g. NXP application note AN10963, page 10f.
uint8_t active_axes; ///< Bit mask of moving axes
uint8_t fast_axis; ///< number of the fast axis uint8_t fast_axis; ///< number of the fast axis
/// Endstop homing /// Endstop homing