Avoid runtime floats in Pulley::PlanMove

Using U_mm inside a compilation unit will force the compiler to generate
a runtime copy of the function, and we don't want that.

But there seems also to be an optimization problem with gcc <= 7.x where
even when declaring an inline function constexpr, if called enough
times, the compiler will choose _not_ to evaluate the function at
compile time and thus avoid our compile-time float->integer
conversions...

For this reason, split the body of the function in two parts: the actual
function that uses AxisUnits at runtime for calling motion.PlanMove, and
a wrapper that forces the conversion. By marking this function as
always_inline, the body is correctly evaluated at compile time at each
call site.
pull/185/head
Yuri D'Elia 2022-06-18 00:53:32 +02:00 committed by DRracer
parent de8a2f35ae
commit f8080bc73b
2 changed files with 10 additions and 5 deletions

View File

@ -3,7 +3,6 @@
#include "buttons.h"
#include "globals.h"
#include "leds.h"
#include "motion.h"
#include "permanent_storage.h"
#include "../debug.h"
@ -34,7 +33,7 @@ bool Pulley::Step() {
}
}
void Pulley::PlanMove(unit::U_mm delta, unit::U_mm_s feed_rate, unit::U_mm_s end_rate) {
void Pulley::PlanMove(mm::P_pos_t delta, mm::P_speed_t feed_rate, mm::P_speed_t end_rate) {
mm::motion.PlanMove<mm::Pulley>(delta, feed_rate, end_rate);
state = Moving;
}

View File

@ -1,9 +1,8 @@
/// @file pulley.h
#pragma once
#include "../config/config.h"
#include "axisunit.h"
#include "../unit.h"
#include "movable_base.h"
#include "motion.h"
namespace modules {
@ -25,7 +24,14 @@ public:
/// @returns true if the pulley is ready to accept new commands (i.e. it has finished the last operation)
bool Step();
void PlanMove(unit::U_mm delta, unit::U_mm_s feed_rate, unit::U_mm_s end_rate = { 0 });
void PlanMove(mm::P_pos_t delta, mm::P_speed_t feed_rate, mm::P_speed_t end_rate = { 0 });
// NOTE: always_inline is required here to force gcc <= 7.x to evaluate each call at compile time
void __attribute__((always_inline)) PlanMove(unit::U_mm delta, unit::U_mm_s feed_rate, unit::U_mm_s end_rate = { 0 }) {
PlanMove(mm::unitToAxisUnit<mm::P_pos_t>(delta),
mm::unitToAxisUnit<mm::P_speed_t>(feed_rate),
mm::unitToAxisUnit<mm::P_speed_t>(end_rate));
}
/// @returns rounded current position (rotation) of the Pulley
/// This exists purely to avoid expensive float (long double) computations of distance traveled by the filament