当前位置:  开发笔记 > 后端 > 正文

两个256位整数的按位xor

如何解决《两个256位整数的按位xor》经验,为你挑选了1个好方法。

我有一个AVX CPU(不支持AVX2),我想计算两个256位整数的按位xor.

由于_mm256_xor_si256仅在AVX2上可用,我可以将这256位加载为__m256使用_mm256_load_ps,然后执行a _mm256_xor_ps.这会产生预期的结果吗?

我主要担心的是,如果内存内容不是有效的浮点数,_mm256_load_ps那么寄存器中的位不会与寄存器中的位完全相同吗?

谢谢.



1> Peter Cordes..:

首先,如果你正在使用256b整数做其他事情(比如加/减/乘),将它们放入向量寄存器只是为了偶尔的异或可能不值得转移它们的开销.如果寄存器中已有两个数字(使用最多8个寄存器),则只有四条xor指令可以获得结果(mov如果需要避免覆盖目标,则只有4 条指令).破坏性版本可以在SnB上每1.33个时钟周期运行一次,或者在Haswell及更高版本上每个时钟运行一个.(xor可以在4个ALU端口中的任何一个上运行).所以如果你只是xor在某些add/adc或其他什么之间做一个,坚持使用整数.

以64b块存储到内存然后执行128b或256b负载会导致存储转发失败,从而增加了几个延迟周期.使用movq/ pinsrq将花费更多的执行资源xor.走另一条路并没有那么糟糕:256b商店 - > 64b负载适用于商店转发. movq/ pextrq仍然很糟糕,但会有更低的延迟(以更多uops为代价).


FP加载/存储/按位操作在架构上保证不产生FP异常,即使在表示信令NaN的位模式上使用时也是如此.只有实际的FP数学指令列出了数学异常:

VADDPS

SIMD浮点异常
溢出,下溢,无效,精度,非正常.

VMOVAPS

SIMD浮点异常
无.

(来自英特尔的insn参考手册.请参阅x86 wiki以获取该链接和其他内容.)

在英特尔硬件上,加载/存储的风格可以在没有额外延迟的情况下进入FP或整数域.无论数据来自何处,AMD都使用类似的行为,无论使用何种风格的加载/存储.

不同风格的向量移动指令实际上对于寄存器<-register移动很重要.在Intel Nehalem上,使用错误的mov指令可能会导致旁路延迟.在AMD Bulldozer系列中,通过寄存器重命名处理移动而不是实际复制数据(如Intel IvB及更高版本),dest寄存器继承了src寄存器写入的域.

我读过的现有设计没有movapd任何不同的处理方式movaps.据推测,英特尔movapd为解码简单性创建了与未来规划相同的功能(例如,允许设计中存在双域和单域,具有不同转发网络的设计).(movapdmovaps66h前缀的,就像所有其他的SSE指令只是拥有的双版本66h前缀字节的上涨,或者F2代替F3了标量指令.)

显然AMD设计了带有辅助信息的FP矢量标签,因为例如,当使用输出addps作为输入时,Agner Fog发现了很大的延迟addpd.我不认为movaps两个addpd指令之间,甚至xorps会导致这个问题:只有实际的FP数学.(FP按位布尔运算是Bulldozer-family上的整数域.)


Intel SnB/IvB(唯一具有AVX而非AVX2的Intel CPU)的理论吞吐量:

使用AVX进行256b操作 xorps

VMOVDQU   ymm0, [A]
VXORPS    ymm0, ymm0, [B]
VMOVDQU   [result], ymm0

由于流水线宽度为4个融合域uops,因此3个融合域uop可以每0.75个周期发出一个.(假设你用于B的寻址模式和结果可以微融合,否则它是5个融合域uops.)

加载端口:SnB上的256b加载/存储需要2个周期(分成128b两半),但这会释放存储器使用的端口2/3上的AGU.有一个专用的存储数据端口,但存储地址计算需要来自加载端口的AGU.

因此,只有128b或更小的加载/存储,SnB/IvB每个周期可以维持两个存储器操作(其中至多一个是存储).对于256b操作,SnB/IvB理论上可以支持两个256b负载和每两个周期一个256b存储.但是,缓存库冲突通常会使这种情况变得不可能.

Haswell有一个专用的存储地址端口,每个周期可以支持两个256b负载和一个256b存储,并且没有缓存存储区冲突.因此,当所有内容都在L1缓存中时,Haswell会更快.

底线:理论上(没有缓存库冲突),这应该使SnB的加载和存储端口饱和,每个周期处理128b.xorps每两个时钟需要一次Port5(唯一可以运行的端口).


128b操作

VMOVDQU   xmm0, [A]
VMOVDQU   xmm1, [A+16]
VPXOR     xmm0, xmm0, [B]
VPXOR     xmm1, xmm1, [B+16]
VMOVDQU   [result],    xmm0
VMOVDQU   [result+16], xmm1

这将成为地址生成的瓶颈,因为SnB每个周期只能维持两个128b内存操作.它还将在uop缓存中使用2倍的空间,以及更多的x86机器代码大小.除非缓存库冲突,否则这应该以每3个时钟一个256b-xor的吞吐量运行.


在寄存器中

在寄存器之间,每个时钟一个256b VXORPS和两个128b VPXOR将使SnB饱和.在Haswell上,VPXOR每个时钟三个AVX2 256b 将在每个周期中提供最多的异或.(XORPSPXOR做同样的事情,但是XORPS输出可以转发到FP执行单元而没有额外的转发延迟周期.我想只有一个执行单元的接线在FP域中有一个XOR结果,所以Intel CPUs后Nehalem只在一个端口上运行XORPS.)


Z Boson的混合理念:

VMOVDQU   ymm0, [A]
VMOVDQU   ymm4, [B]
VEXTRACTF128 xmm1, ymm0, 1
VEXTRACTF128 xmm5, ymm1, 1
VPXOR     xmm0, xmm0, xmm4
VPXOR     xmm1, xmm1, xmm5
VMOVDQU   [res],    xmm0
VMOVDQU   [res+16], xmm1

甚至更多的融合域uops(8),而不仅仅是做128b-一切.

加载/存储:两个256b负载留下两个备用周期,用于生成两个存储地址,因此这仍然可以在两个负载/每个周期128b的一个存储中运行.

ALU:两个端口-5 uops(vextractf128),两个端口0/1/5 uop(vpxor).

因此,每2个时钟的吞吐量仍然是一个256b的吞吐量,但它的资源更多,并且在3指令256b版本上没有优势(在Intel上).

推荐阅读
农大军乐团_697
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有