gpt4 book ai didi

x86 - AVX2编译的程序是否仍然可以使用支持AVX-512的CPU的32个寄存器?

转载 作者:行者123 更新时间:2023-12-04 14:26:18 24 4
gpt4 key购买 nike

假设以AVX2为目标的编译并具有C ++内在函数,如果我编写一个使用每个body-body计算17个寄存器的nbody算法,则可以将第17个寄存器间接(寄存器重命名硬件)或直接(Visual Studio编译器,gcc编译器)映射到AVX上-512寄存器以减少对内存的依赖?例如,Skylake体系结构具有1或2个AVX-512 fma单元。这个数字也会改变可用的寄存器总数吗? (具体来说,是Xeon Silver 4114 CPU)

如果可行,它如何运作?当所有指令均小于等于AVX2时,第一硬件线程使用每个ZMM向量的前一半,第二硬件线程使用每个ZMM向量的后一半?



编辑:如果在目标计算机上进行在线编译(例如,使用OpenCL)怎么办?司机可以为我做以上注册使用情况吗?

最佳答案

TL:DR:使用-march=skylake-avx512进行编译,以使编译器使用EVEX前缀访问ymm16-31,以便(希望)一次使具有17个__m256值的代码“实时”存活(更好)。




例如,Skylake体系结构具有1或2个AVX-512 fma单元。这个数字也会改变可用的寄存器总数吗?


不,无论存在多少FMA执行单元,物理寄存器文件在所有Skylake CPU中的大小都是相同的。这些东西是完全正交的。

对于64位AVX2,体系结构YMM寄存器的数量为16,对于64位AVX512VL,其数量为32。在32位代码中,即使使用AVX512,也总是只有8个向量寄存器可用。 (因此,对于大多数高性能计算,32位是非常过时的。)

请注意,AVX512F仅包含大多数指令的ZMM版本。您需要AVX512VL来执行大多数YMM指令的EVEX编码。

具有AVX512VL + AVX2的YMM16-31需要更长的EVEX编码,但是所有操作数都在低16位的指令可以使用指令的较短VEX前缀AVX / AVX2形式。 (混合使用VEX和EVEX编码不会产生任何损失,因此VEX对于代码大小而言更为可取。但是,如果避免使用y / zmm0-y / zmm15,则不需要VZEROUPPER; legacy-SSE指令不能使用xmm16-31因此没有任何问题。)

同样,这与存在的FMA执行单元无关。


如果我使用每个人体计算使用17个寄存器来编写nbody算法,则可以间接映射第17个寄存器(寄存器重命名硬件)


不,这不是CPU和机器代码的工作方式。在机器码中,只有4位(不使用仅AVX512编码)或5位(有AVX512编码)字段来指定指令的寄存器操作数。

如果您的代码需要同时具有17个矢量值以使其处于“活动”状态,则在针对x86-64 AVX2(架构上仅具有16个YMM寄存器)时,编译器将不得不发出指令以溢出/重新加载其中之一。即,它具有16个不同的名称,CPU可以将其重命名为其更大的内部寄存器文件。

如果寄存器重命名解决了整个问题,则x86-64不会费心将体系结构寄存器的数量从8整数/ 8 xmm增加到16整数/ 16 xmm。

这就是为什么AVX512花费3个额外的位(dst,src1和src2每个位)以允许访问32个体系结构向量寄存器(在64位模式下; 32位模式仍然只有8个)。



寄存器重命名允许将同一体系结构寄存器重用于不同的值,而不会产生任何虚假依赖。即avoids WAR and WAW hazards;它是使混乱的执行工作生效的“魔术”的一部分。在考虑ILP和无序执行时,它有助于保持更多的价值,但在任何时候都不能以简单的程序执行顺序在体系结构寄存器中拥有更多的价值。

例如,以下循环仅需要3个体系结构寄存器,并且每个迭代都是独立的(除了指针增加,没有循环承载的依赖项)。

.loop:
vaddps ymm0, ymm1, [rsi] ; ymm0 = ymm1, [src]
vmulps ymm0, ymm0, ymm2 ; ymm0 *= ymm2
vmovaps [rsi+rdx], ymm0 ; dst = src + (dst_start - src_start). Stays micro-fused on Haswell+

add rsi, 32
cmp rsi, rcx ; }while(rsi < end_src)
jb .loop


但是,从一次写入ymm0到一次迭代中的最后一次读取有8个周期的延迟链(Skylake addps / mulps分别为4个周期),这将成为CPU的瓶颈,而无需重命名寄存器。直到该迭代中的 vmovaps读取了值,下一次迭代才能写入ymm0。

但是在乱序的CPU上,一次同时进行多个迭代,每次对ymm0的写入都被重命名以写入不同的物理寄存器。忽略前端瓶颈(假装我们已经展开),CPU可以在飞行中保持足够的迭代次数,以使FMA单元达到饱和,每个时钟使用2个addps / mulps uops,使用大约8个物理寄存器。 (或者更多,因为实际上直到退休后才可以释放它们,而不仅仅是在最后一个uop读取完该值之后)。

有限的物理寄存器文件大小 can be the limit on the out-of-order windows size, instead of the ROB or scheduler size

(我们曾一度认为,Skylake-AVX512基于 this result使用2个PRF条目作为ZMM寄存器,但后来更详细的实验表明,AVX512模式可为更宽的PRF供电,或为上层通道供电以补充现有的PRF,因此在AVX512模式下的SKX仍具有与256位物理寄存器相同的512位物理寄存器数量,请参见 discussion between @BeeOnRope and @Mysticial。我认为在某处可以更好地记录实验+结果,但我找不到它)



相关文章: Why does mulss take only 3 cycles on Haswell, different from Agner's instruction tables?(答案:没有; OP对寄存器重用感到困惑。我的答案详细解释了很多有趣的性能试验,其中涉及多个向量累加器。)

关于x86 - AVX2编译的程序是否仍然可以使用支持AVX-512的CPU的32个寄存器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48892733/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com