如何解决可以“交换 nybble”和“字节掩码”技巧将多字节逻辑移位 4 比使用位移链的幼稚方法快得多 使用任何类型的 nybble 交换字节掩码技巧,这是否可以通过更接近每字节一个周期的时间复杂度来完成,而不是接近每比特一个周期的时间复杂度?
我正在编写一个定点 (16Q16) 算法,该算法使用 Newton–Raphson 方法 outlined on Wikipedia.(相关 SE 问题 HERE。)
第一步需要逻辑右移 1-16 位。我的 cpu 是一个 8 位微控制器,所以没有桶形移位器;硬件只能支持移位 1 位。 (相关的 SE 问题 HERE。)要移位 n
位,可以使用单移位指令 n
次,但是,这具有显着的最坏情况时序。这种糟糕的最坏情况在加上移位的多字节性质时变得非常糟糕。如果移动1个字节1次需要1个周期,我们可以很快想象当需要移动16个字节16次时的问题。请记住,这只是第 1 步。
明显的优化就是分而治之;手动计算 2 的所有幂。第一个简单的情况是移位 16 和 8,因为这只是将内存索引更改为定点数。这样做只需大约 4 个周期/指令即可将 16 字节移位 16 位,速度比“单移位链接”提高了 64 倍。
我遇到的问题是令人讨厌的 4 班制。
我的直觉,以及这里和那里的一些片段和帖子,告诉我他们存在一种将 nybble 交换指令与位掩码和逻辑操作相结合的有效方法,以创建一种“nybble 交换拉链效果”可以将任意长度的数组最佳地移动 4 位。 (相关 SE 问题 HERE。答案 3 的链接)
我知道它至少可以从根本上完成,因为我有一个仅使用 SWAP、XOR 和 AND 指令的概念教授。我也知道它可以更快地完成,因为我所拥有的比简单的移位链方法快一个周期(大声笑,是的,一个)。 (见下面的代码框)我不知道的是...
使用任何类型的 nybble 交换字节掩码技巧,这是否可以通过更接近每字节一个周期的时间复杂度来完成,而不是接近每比特一个周期的时间复杂度?
注意:这是 PIC18 ASM,但很明显发生了什么。关于如何大幅改进这一点的任何建议都将是这个问题的答案。是的!我意识到它很可能已经接近最优,但实现 4 移位是几段代码中反复出现的热点。我希望从每个块中削减至少一条指令。切掉两个会很棒。
; Shift the denominator -> 4 (19 cyc)
;------------------------------------------
SWAPF Denom+3,W,BANKED
MOVWF Denom+3,BANKED
ANDLW 0xF0
XORWF Denom+3,F,BANKED
SWAPF Denom+2,BANKED
XORWF Denom+2,BANKED
ANDLW 0xF0
XORWF Denom+2,BANKED
SWAPF Denom+1,BANKED
XORWF Denom+1,BANKED
ANDLW 0xF0
XORWF Denom+1,BANKED
SWAPF Denom+0,BANKED
XORWF Denom+0,BANKED
ANDLW 0xF0
XORWF Denom+0,BANKED
;------------------------------------------
解决方法
您的解决方案涉及 19 条指令(每条指令需要一个周期),但简单的解决方案只需要 18 条:
RRCF Denom+3,F,BANKED
RRCF Denom+2,BANKED
RRCF Denom+1,BANKED
RRCF Denom+0,BANKED
RRCF Denom+3,BANKED
MOVLW 0x0F
ANDWF Denom+3,BANKED
我想不出比实际执行这种转变更快的东西了。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。