为了实施log(x)
, you want尾数和指数为float
, and vgetmantps
/ vgetexpps
非常适合它。AVX2 中 log2(__m256d) 的高效实现 https://stackoverflow.com/questions/45770089/efficient-implementation-of-log2-m256d-in-avx2。这就是这些指令的用途,并且确实可以加速快速逼近log(2)
。 (此外,它可以将有效数标准化为 -0.5 .. +0.5 而不是 1 .. 2.0 或其他整齐的范围,以创建多项式近似的输入log(x+1)
管他呢。看its docs http://felixcloutier.com/x86/VGETMANTPS.html.)
如果您只想将尾数作为整数,那么请确保将其他位与其他位相加,然后您就可以在一条指令中完成。
(但请记住,对于 NaN,尾数是 NaN 有效负载,因此如果您需要对 NaN 执行不同的操作,则需要检查指数。)
将数字从 float 转换为 int 再转换回 float 的延迟是多少?
您已经有了 Agner Fog 的说明表(https://agner.org/optimize/ https://agner.org/optimize/)。在 Skylake(SKL 和 SKX)上VCVT(T) PS2DQ
FMA 端口的延迟为 4c,另一个方向也是如此。
或者您是否询问使用 FP 指令输出的旁路延迟,例如andps
作为整数指令的输入?
Agner Fog 的 microarch PDF 提供了一些有关在 vec-int 和 fp 域之间发送数据的旁路延迟的信息,但具体细节不多。
Skylake 的旁路延迟很奇怪:与之前的 uarches 不同,它取决于指令实际选择的端口。andps
如果在端口 5 上运行,则 FP 指令之间没有旁路延迟,但如果在 p0 或 p1 上运行,则会有额外的 1c 延迟。
请参阅英特尔优化手册,了解按域+执行端口细分的跨域延迟表。
(更奇怪的是,这种旁路延迟延迟会永远影响该寄存器,即使它已经明确写回物理寄存器并且没有通过旁路网络转发。vpaddd xmm0, xmm1, xmm2
如果任一输入来自vmulps
。但一些洗牌和其他指令在这两个域中都有效。我尝试这个已经有一段时间了,而且我没有检查我的笔记,所以这个例子可能不完全正确,但它是这样的。)
(英特尔的优化手册没有提到这种永久效果,这种效果会持续到您用新值覆盖架构寄存器为止。因此,在使用整数指令的循环之前创建 FP 常量时要小心。)