开源改变世界

关键路径中的周期节省 #1039

推推 grbl 2年前 (2023-01-23) 122次浏览

关闭
J-Dunn 打开了这个问题 2016 年 7 月 13 日 · 5 条评论
关闭

关键路径中的周期节省#1039

J-Dunn 打开了这个问题 2016 年 7 月 13 日 · 5 条评论

注释

关键路径中的周期节省 #1039
J-邓恩 评论了 2016 年 7 月 13 日  

probe.c 说:

// Monitors probe pin state and records the system position when detected. Called by the
// stepper ISR per ISR tick.
// NOTE: This function must be extremely efficient as to not bog down the stepper ISR.
void probe_state_monitor()
{
  if (sys_probe_state == PROBE_ACTIVE) {

因为很少需要探测,所以这个调用毫无意义地加载了步进 ISR 中的关键路径。这个测试应该在调用不在其中的过程之前完成。

建议stepper.c

  // Check probing state.
   if (sys.probe_state == PROBE_ACTIVE)  probe_state_monitor();

我没有进行字节计数,但在关键路径中避免调用开销会很好。

关键路径中的周期节省 #1039
成员

真的。我想我这样做是为了在 probe.c 文件中而不是在 stepper.c 文件中完成特定于探测器的测试。另外,我认为这无论如何都会被编译器内联,所以它不应该影响性能。

关键路径中的周期节省 #1039
作者

它似乎没有内联:

    4350:   39 c1           rjmp    .+626       ; 0x45c4 <__vector_11+0x450>
    4352:   0e 94 ed 09     call    0x13da  ; 0x13da <probe_state_monitor>
    4356:   10 92 a0 04     sts 0x04A0, r1
    435a:   10 92 9f 04     sts 0x049F, r1


000013da <probe_state_monitor>:
    13da:   80 91 4e 05     lds r24, 0x054E
    13de:   81 30           cpi r24, 0x01   ; 1
    13e0:   a1 f4           brne    .+40        ; 0x140a <probe_state_monitor+0x30>
    13e2:   0e 94 e7 09     call    0x13ce  ; 0x13ce <probe_get_state>

IIRC 只有在同一个文件中才会发生。

至少这里不需要压入和弹出寄存器。
在探测时,额外的一点无关紧要,因此在这种情况下,单独的文件和调用无关紧要。

不久之前,您曾在任何地方询问任何人在 ISR 中看到的一些速度优化,所以这是一个建议。

关键路径中的周期节省 #1039
成员

@J-Dunn: 感谢您的建议和检查内联。我会将此改进放入 v1.0 中,而 v0.9 master 保持原样。

关键路径中的周期节省 #1039
拆分n2 评论了 2016 年 7 月 13 日  

我开始吟唱,1.0 1.0 1.0 1dot0 1dot0 1dot0 1DOT0 1DOT0 1DOT0 ONEDOTZERO ONEDOTZERO ONEDOTZERO ONEDOTZERO ONEDOTZERO ONEDOTZERO,声音越来越大!!!!!!继续努力@chamnit非常感谢您的努力,如果有办法,我很想成为早期采用者?干杯,理查德

关键路径中的周期节省 #1039
作者
J-邓恩 评论了 2016 年 7 月 23 日  

从 ISR(SERIAL_RX) 中调用的函数中的另一个 6 字节保存,也使得它更容易阅读。

uint8_t serial_get_rx_buffer_count()
{
/*  uint8_t rtail = serial_rx_buffer_tail; // Copy to limit multiple calls to volatile
  if (serial_rx_buffer_head >= rtail) { return(serial_rx_buffer_head-rtail); }
  return (RX_BUFFER_SIZE - (rtail-serial_rx_buffer_head));
*/
  uint8_t len = serial_rx_buffer_head -serial_rx_buffer_tail;
  if (len >= 0) { return(len); }
  return (RX_BUFFER_SIZE + len);
}

同样的事情可以在 serial_get_tx_buffer_count() 中完成,尽管它通常是未使用和优化的。

编辑
糟糕,这需要是一个 int8_t,奇怪的是只节省 2 个字节 :(

尽管如此,它确实扫描得更好。

喜欢 (0)