【发布时间】:2020-02-27 19:54:19
【问题描述】:
我目前正在将 nacl 库转换为 risc-v。我已经有 poly1305 工作。我正在尝试使用 risc-v 核心指令集来做到这一点,所以我没有乘数。 Pol1305 的算法目前正在使用 ceil(m/16)*17*17 8 位乘法,其中 m 是以字节为单位的消息长度(以 2^8 为模 2^130-5 乘以两个 2^130 整数) .所以我想用一个快速的乘法算法来保持它的速度。
目前我有用于乘法的移位加法算法。但是,对于 8 位值,这需要 63 个周期,因为我需要避免分支(定时侧通道),因此涉及一些需要更多周期的掩码。
andi t2, t0, 1 //t0 is the multiplier
sub t2, zero, t2 //creating a mask
and t3, t1, t2 //applying the mask to the multiplicand
add a0, a0, t3 //doing the add
srli t0, t0, 1 //shifting the multiplier
slli t1, t1, 1 //shifting the multiplicand
这给了我每次乘法 63 个周期的有效结果。问题是对于 131 字节的消息,程序的总执行时间是 175219 个周期。其中 9*17*17*63 = 163863 个周期用于乘法。我想改进。
【问题讨论】:
-
对分支机构的禁令听起来像加密货币。是否允许数据相关的内存访问?对于四分之一平方乘法或类似的
-
你的意思是这个6条指令的代码块在你关心的核心上需要63个周期吗?还是在一个循环中进行 32 次迭代需要 63 个循环?您应该至少显示该内部循环。 (你的意思是你“不允许”使用分支是什么意思?你真的是说分支对于随机数据会更慢,所以你选择避免它吗?)另外为什么使用基数 2^8,而不是例如base 2^32 使用寄存器的全宽?或者至少基数 2^16,或者如果您需要为手动进位传播留出空间,则可能是 2^30。 (IIRC RISC-V 没有标志,所以 add-with-carry 需要仿真。)
-
你的核心是超标量吗?你能通过交错两个完整的乘法块来暴露 ILP 吗?
-
可能的微优化:使用 SAR by 31 向所有位置广播位,而不是和/sub。 (要将低位移到顶部位置,可以向右旋转?或者从循环外的移位开始进行设置。)如果您在移位 ALU 吞吐量上遇到瓶颈,您可以用
add same,same替换 left-shift -
@harold 是的,它是加密的,不允许数据相关的内存访问,但无论如何我都会研究四分之一平方乘法来检查。
标签: assembly multiplication micro-optimization riscv modular-arithmetic