当前位置: 首页 > 知识库问答 >
问题:

首次使用AVX 256位向量会减慢128位向量和AVX标量操作

夹谷茂
2023-03-14

最初,我试图重现Agner Fog的微体系结构指南部分“YMM和ZMM矢量指令的预热期”中描述的效果,其中指出:

处理器在不使用时关闭向量执行单元的上部,以节省电源。在大约56000个时钟周期或14μs的初始预热期间,具有256位向量的指令的吞吐量大约是正常的4.5倍。

我得到了减速,尽管它看起来更接近~2x而不是4.5x。但我发现在我的CPU(英特尔i7-9750H咖啡湖)上,减速不仅影响256位操作,还影响128位向量操作和标量浮点操作(甚至是XMM触摸指令之后的N个仅限GPR的指令)。

基准项目代码

# Compile and run:
# clang++ ymm-throttle.S && ./a.out

.intel_syntax noprefix

.data
L_F0:
  .asciz "ref cycles = %u\n"

.p2align 5
L_C0:
  .long 1
  .long 2
  .long 3
  .long 4
  .long 1
  .long 2
  .long 3
  .long 4

.text

.set initial_scalar_warmup, 5*1000*1000
.set iteration_count, 30*1000
.set wait_count, 50*1000

.global _main
_main:
  # ---------- Initial warm-up
  # It seems that we enter _main (at least in MacOS 11.2.2) in a "ymm warmed-up" state.
  #
  # Initial warm-up loop below is long enough for the processor to switch back to
  # "ymm cold" state. It also may reduce dynamic-frequency scaling related measurements
  # deviations (hopefully CPU is in full boost by the time we finish initial warmup loop).

  vzeroupper

  push rbp
  mov ecx, initial_scalar_warmup

.p2align 4
_initial_loop:
  add eax, 1
  add edi, 1
  add edx, 1

  dec ecx
  jnz _initial_loop

  # --------- Measure XMM

  # TOUCH YMM.
  # Test to see effect of touching unrelated YMM register
  # on XMM performance.
  # If "vpxor ymm9" below is commented out, then the xmm_loop below
  # runs a lot faster (~2x faster).
  vpxor ymm9, ymm9, ymm9

  mov ecx, iteration_count
  rdtsc
  mov esi, eax

  vpxor xmm0, xmm0, xmm0
  vpxor xmm1, xmm1, xmm1
  vpxor xmm2, xmm2, xmm2
  vmovdqa xmm3, [rip + L_C0]

.p2align 5
_xmm_loop:
  # Here we only do XMM (128-bit) VEX-encoded op. But it is triggering execution throttling.
  vpaddd xmm0, xmm3, xmm3
  add edi, 1
  add eax, 1

  dec ecx
  jnz _xmm_loop

  lfence
  rdtsc
  sub eax, esi
  mov esi, eax  # ESI = ref cycles count

  # ------------- Print results

  lea rdi, [rip + L_F0]
  xor eax, eax
  call _printf

  vzeroupper
  xor eax, eax
  pop rbp
  ret​

问题:我的基准是否正确?下面对发生的事情的描述似乎合理吗?

CPU处于AVX-冷状态(约675µs内没有执行256位/512位指令)遇到带有YMM(ZMM)目标寄存器的单个指令。CPU立即切换到某种“过渡到AVX-暖”状态。这大概需要Agner指南中提到的约100-200个周期。并且这个“过渡”周期持续约56'000个周期。

在过渡期间,GPR代码可以正常执行,但任何具有向量目标寄存器的指令(包括128位XMM或标量浮点指令,甚至包括vmovq xmm0、rax)都会对整个执行管道应用限制。这会影响紧跟在该指令之后的仅GPR代码N个周期(不确定有多少个周期;可能有十几个周期的指令)。

节流可能会限制分配给执行单元的µop的数量(无论这些µop是什么;只要至少有一个µop具有向量目标寄存器)?

对我来说,这里的新功能是,我认为在过渡期内,节流将仅适用于256位(和512位)指令,但似乎任何具有向量寄存器目标的指令都会受到影响(以及仅在指令之后立即测量20-60的GPR;在我的系统上无法更精确地测量)。

相关报道:特拉维斯·唐斯博客上一篇文章的“仅电压转换”部分可能描述了同样的效果。虽然作者测量了过渡期间YMM向量的性能,但得出的结论是,当过渡期间遇到向量寄存器接触指令时,被拆分的不是向量的上部,而是应用于整个管道的节流。(编辑:这篇博文没有测量过渡期内的XMM寄存器,这正是本文所测量的)。

共有1个答案

缪风史
2023-03-14

即使对于窄SIMD指令,您也会看到节流,这是我称之为隐式加宽的行为的副作用。

基本上,在现代英特尔上,如果在ymm0到ymm15范围内的任何寄存器上的128-255高位脏了,任何SIMD指令都会在内部扩展到256位,因为高位需要归零,这需要寄存器文件中的全部256位寄存器通电,可能还需要256位ALU路径。因此,该指令用于AVX频率,就好像它是256位宽的一样。

类似地,如果任何zmm寄存器上的位256到511在zmm0到zmm15的范围内变脏,则操作会隐式加宽到512位。

对于轻指令与重指令,加宽指令的类型与全宽指令的类型相同。也就是说,将128位FMA扩展到512位的FMA充当“重AVX-512”,即使仅发生128位FMA。

这适用于所有使用xmm/ymm寄存器的指令,甚至标量FP操作。

请注意,这不仅仅适用于此限制期:这意味着如果您的上限不干净,则窄SIMD指令(或标量FP)将导致转换到更保守的DVFS状态,就像全宽指令一样。

 类似资料:
  • 我在一个项目中工作,在这个项目中,我通过XML流向web服务发帖。在这种情况下,提供程序请求使用密码块链接(CBC)模式下的高级加密标准(AES)和128位初始化向量对路由xml进行加密。我是用VB.NET编码的,从我可以看出我已经满足了他们所有的加密要求,但当我提交帖子时,我总是得到一个“无效的路由输入加密”的错误响应。我没有做很多与加密,所以我希望有人与一些加密经验可以帮助我在这里。它失败是因

  • 问题内容: 在当前的作业中,我需要处理位向量,但是我不确定如何在Python中执行此操作。它们应该能够从4位到20位。我以前从未使用过位向量,但是我猜想一个人会创建一个使用无与伦比的字节数组,这些数组是使用通常的AND / OR / XOR操作进行操作的。 这里的 重要限制 是:除了标准Python提供的库之外,我不能依赖 任何 其他库。 我想我知道如何使用8位无符号字节数组在C中做到这一点:例如

  • 问题内容: 只是在ThreeJS中对r67-r69进行了更新,最终遇到了将其位置指向一个(相同)向量的问题。 在执行此操作之前,请执行以下操作: 这使得当我移动其中一个网格时,它也可以移动另一个网格。 在r69中,位置矢量保持不变(也称为0、0、0),这意味着每当我对另一个网格进行模式化时,我都必须手动设置每个网格的X,Y和Z坐标。 我在这里想找点零钱吗?或者我应该怎么做才能解决这个问题? 问题答

  • 问题内容: 有没有一种很好的方法来区分python中的行向量和列向量?到目前为止,我正在使用numpy和scipy,到目前为止,我看到的是,如果我要给一个向量,说 他们无法说天气,我的意思是行或列向量。此外: 在“现实世界”中哪一个根本是不正确的。我意识到上述模块中向量上的大多数功能都不需要区分。例如,或者我想为自己的方便而与众不同。 问题答案: 您可以通过向数组添加另一个维度来明确区分。 现在将

  • 矢量或者说向量,可以通过2~4个分量表示一个向量,比如通过vec3(1,0,0)表示三维空间中一个沿着x轴正方向的三维方向向量,如果你有高中数学的基础,应该对向量有一定的了解,对于三维坐标的相关几何运算也有一定的概念。 关键字 数据类型 vec2 二维向量,具有xy两个分量,分量是浮点数 vec3 三维向量 ,具有xyz三个分量,分量是浮点数 vec4 四维向量 ,具有xyzw四个分量,分量是浮点

  • 在最近的一次采访中,我建议使用向量 编码过程结束后,他们说在向量上使用pair是个好主意,并要求我详细说明我之前所说的“更重”是什么意思。不幸的是,我无法详细说明。是的,我知道我们只能在一对中输入两个值,但在一个向量中可以输入更多的值,并且当向量的大小==容量等时,该向量会自动调整大小。但是我应该如何回答他们的问题?为什么具体使用<代码>向量