- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在英特尔内部函数指南中,vmulpd
和vfmadd213pd
延迟为 5,vaddpd
延迟为 3。
我编写了一些测试代码,但所有结果都慢了 1 个周期。
这是我的测试代码:
.CODE
test_latency PROC
vxorpd ymm0, ymm0, ymm0
vxorpd ymm1, ymm1, ymm1
loop_start:
vmulpd ymm0, ymm0, ymm1
vmulpd ymm0, ymm0, ymm1
vmulpd ymm0, ymm0, ymm1
vmulpd ymm0, ymm0, ymm1
sub rcx, 4
jg loop_start
ret
test_latency ENDP
END
#include <stdio.h>
#include <omp.h>
#include <stdint.h>
#include <windows.h>
extern "C" void test_latency(int64_t n);
int main()
{
SetThreadAffinityMask(GetCurrentThread(), 1); // Avoid context switch
int64_t n = (int64_t)3e9;
double start = omp_get_wtime();
test_latency(n);
double end = omp_get_wtime();
double time = end - start;
double freq = 3.3e9; // My CPU frequency
double latency = freq * time / n;
printf("latency = %f\n", latency);
}
我的CPU是Core i5 4590,我将其频率锁定在3.3GHz。输出为:latency = 6.102484
.
奇怪的是,如果我改变 vmulpd ymm0, ymm0, ymm1
至vmulpd ymm0, ymm0, ymm0
,则输出变为:latency = 5.093745
.
有解释吗?我的测试代码有问题吗?
更多结果
results on Core i5 4590 @3.3GHz
vmulpd ymm0, ymm0, ymm1 6.056094
vmulpd ymm0, ymm0, ymm0 5.054515
vaddpd ymm0, ymm0, ymm1 4.038062
vaddpd ymm0, ymm0, ymm0 3.029360
vfmadd213pd ymm0, ymm0, ymm1 6.052501
vfmadd213pd ymm0, ymm1, ymm0 6.053163
vfmadd213pd ymm0, ymm1, ymm1 6.055160
vfmadd213pd ymm0, ymm0, ymm0 5.041532
(without vzeroupper)
vmulpd xmm0, xmm0, xmm1 6.050404
vmulpd xmm0, xmm0, xmm0 5.042191
vaddpd xmm0, xmm0, xmm1 4.044518
vaddpd xmm0, xmm0, xmm0 3.024233
vfmadd213pd xmm0, xmm0, xmm1 6.047219
vfmadd213pd xmm0, xmm1, xmm0 6.046022
vfmadd213pd xmm0, xmm1, xmm1 6.052805
vfmadd213pd xmm0, xmm0, xmm0 5.046843
(with vzeroupper)
vmulpd xmm0, xmm0, xmm1 5.062350
vmulpd xmm0, xmm0, xmm0 5.039132
vaddpd xmm0, xmm0, xmm1 3.019815
vaddpd xmm0, xmm0, xmm0 3.026791
vfmadd213pd xmm0, xmm0, xmm1 5.043748
vfmadd213pd xmm0, xmm1, xmm0 5.051424
vfmadd213pd xmm0, xmm1, xmm1 5.049090
vfmadd213pd xmm0, xmm0, xmm0 5.051947
(without vzeroupper)
mulpd xmm0, xmm1 5.047671
mulpd xmm0, xmm0 5.042176
addpd xmm0, xmm1 3.019492
addpd xmm0, xmm0 3.028642
(with vzeroupper)
mulpd xmm0, xmm1 5.046220
mulpd xmm0, xmm0 5.057278
addpd xmm0, xmm1 3.025577
addpd xmm0, xmm0 3.031238
我的猜测
我改变了test_latency
像这样:
.CODE
test_latency PROC
vxorpd ymm0, ymm0, ymm0
vxorpd ymm1, ymm1, ymm1
loop_start:
vaddpd ymm1, ymm1, ymm1 ; added this line
vmulpd ymm0, ymm0, ymm1
vmulpd ymm0, ymm0, ymm1
vmulpd ymm0, ymm0, ymm1
vmulpd ymm0, ymm0, ymm1
sub rcx, 4
jg loop_start
ret
test_latency ENDP
END
终于得到了5个循环的结果。还有其他指令可以达到同样的效果:
vmovupd ymm1, ymm0
vmovupd ymm1, [mem]
vmovdqu ymm1, [mem]
vxorpd ymm1, ymm1, ymm1
vpxor ymm1, ymm1, ymm1
vmulpd ymm1, ymm1, ymm1
vshufpd ymm1, ymm1, ymm1, 0
但是这些说明不能:
vmovupd ymm1, ymm2 ; suppose ymm2 is zeroed
vpaddq ymm1, ymm1, ymm1
vpmulld ymm1, ymm1, ymm1
vpand ymm1, ymm1, ymm1
对于 ymm 指令,我猜想避免 1 个额外周期的条件是:
至于VEX xmm,情况似乎有点模糊。好像和上半状态有关,但不知道哪个更干净:
vxorpd ymm1, ymm1, ymm1
vxorpd xmm1, xmm1, xmm1
vzeroupper
这个问题对我来说很难。
最佳答案
自从在 Skylake 上注意到它以来,我几年来一直想写一些关于这个的东西。 https://github.com/travisdowns/uarch-bench/wiki/Intel-Performance-Quirks#after-an-integer-to-fp-bypass-latency-can-be-increased-indefinitely
旁路延迟延迟是“粘性的”:整数 SIMD 指令可以“感染”读取该值的所有 future 指令,即使在指令完成很长时间之后也是如此。我很惊讶“感染”在归零惯用法中幸存下来,尤其是像 vxorpd
这样的 FP 归零指令。 ,但我可以在 SKL 上重现这种效果(i7-6700k,在 Linux 上使用 perf
直接在测试循环中计算时钟周期,而不是搞乱时间和频率。)
(在 Skylake 上,在循环发生工作之前,似乎有 3 个或更多 vxorpd
连续归零指令,从而消除了额外的旁路延迟。据我所知,异或归零总是被消除,这与mov-elimination 有时会失败。但也许区别只是在后端的 vpaddb
和第一个 vmulpd
之间创建了一个间隙;在我的测试循环中,我“脏”/污染了之前的寄存器循环。)
(更新:现在再次尝试我的测试代码,即使是 vxorps
似乎也清理了寄存器。也许微代码更新改变了一些东西。)
推测调用者中 YMM1 的某些先前使用涉及整数指令。 (TODO:调查寄存器进入这种状态的常见情况,以及它何时可以在异或归零中幸存!我预计它只会在使用整数指令构造 FP 位模式时发生,包括像 vpcmpeqd ymm1,ymm1,ymm1
这样的东西创建一个 -NaN(全 1 位)。)
在 Skylake 上,我可以通过执行 vaddpd ymm1, ymm1, ymm1
来修复它在循环之前,异或归零之后。 (或者之前;这可能并不重要!这可能是更优化的,将其放在前一个 dep 链的末尾而不是这个的开头。)
正如我所写的in a comment on another question
xsave/rstor can fix the issue where writing a register with aSIMD-integer instruction like paddd creates extra latency indefinitelyfor reading it with an FP instruction, affecting latency from bothinputs. e.g.
paddd xmm0, xmm0
then in a loopaddps xmm1, xmm0
has 5clatency instead of the usual 4, until the next save/restore.It'sbypass latency but still happens even if you don't touch the registeruntil after the paddd has definitely retired (by padding with >ROBuops) before the loop.
; taskset -c 3 perf stat --all-user -etask-clock,context-switches,cpu-migrations,page-faults,cycles,branches,instructions,uops_issued.any,uops_executed.thread -r1 ./bypass-latency
default rel
global _start
_start:
vmovaps xmm1, [one] ; FP load into ymm1 (zeroing the upper lane)
vpaddd ymm1, ymm1,ymm0 ; ymm1 written in the ivec domain
;vxorps ymm1, ymm1,ymm1 ; In 2017, ymm1 still makes vaddps slow (5c) after this
; but I can't reproduce that now with updated microcode.
vxorps ymm0, ymm0, ymm0 ; zeroing-idiom on ymm0
mov rcx, 50000000
align 32 ; doesn't help or hurt, as expected since the bottleneck isn't frontend
.loop:
vaddps ymm0, ymm0,ymm1
vaddps ymm0, ymm0,ymm1
dec rcx
jnz .loop
xor edi,edi
mov eax,231
syscall ; exit_group(0)
section .rodata
align 16
one: times 4 dd 1.0
Perf 在 i7-6700k 上生成静态可执行文件:
Performance counter stats for './foo' (4 runs):
129.01 msec task-clock # 0.998 CPUs utilized ( +- 0.51% )
0 context-switches # 0.000 K/sec
0 cpu-migrations # 0.000 K/sec
2 page-faults # 0.016 K/sec
500,053,798 cycles # 3.876 GHz ( +- 0.00% )
50,000,042 branches # 387.576 M/sec ( +- 0.00% )
200,000,059 instructions # 0.40 insn per cycle ( +- 0.00% )
150,020,084 uops_issued.any # 1162.883 M/sec ( +- 0.00% )
150,014,866 uops_executed.thread # 1162.842 M/sec ( +- 0.00% )
0.129244 +- 0.000670 seconds time elapsed ( +- 0.52% )
500M 迭代的 500M 周期 = 2x 10 周期循环携带依赖 vaddps
,或各 5 个。
关于performance - Haswell AVX/FMA 延迟测试比英特尔指南慢 1 个周期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64116679/
我在 Haswell CPU(Intel Core i7-4790)上安装了 perf。但“性能列表”不包括“stalled-cycles-frontend”或“stalled-cycles-back
关闭。这个问题不满足Stack Overflow guidelines .它目前不接受答案。 想改善这个问题吗?更新问题,使其成为 on-topic对于堆栈溢出。 7年前关闭。 Improve thi
我正在使用 Intel Haswell CPU 的 FMA 指令来优化一些计算。 但是,我发现即使我将 MXCSR 寄存器设置为 DNZ 和 FTZ 模式,这些指令也会生成异常。 我如何强制这些 FM
哪些编译器(截至 2014 年 5 月)能够生成使用事务内存功能(受限事务内存,而不仅仅是锁省略)的代码? 最佳答案 GCC,截至 version 4.8支持英特尔 RTM: Support for
我正在尝试使用自上而下的微架构分析方法 (TMAM) 来分析 Intel Haswell CPU (Intel® Core™ i7-4900MQ) 上的执行情况,如 Intel® 64 and IA-
在准备一些演示文稿时,我突然想到,我不知道 Haswell 内核一次可以执行的整数运算数量的理论限制是多少。 我曾经天真地假设“Intel 内核具有 HT,但这可能会并行化不同类型的工作,因此内核可能
要知道,haswell是英特尔作为Ivy Bridge微架构的“第四代核心”继承者而开发的一种处理器微架构的代号。 1英特尔正式发布了基于这种微架构的CPU... More 但是,我想知道如何通过在
这个循环在 Intel Conroe/Merom 上每 3 个周期运行一次迭代,如预期的那样在 imul 吞吐量上出现瓶颈。但是在 Haswell/Skylake 上,它每 11 个周期运行一次迭代,
我正在查看AVX programming reference 。 new Haswell instructions包括一些期待已久的“聚集”负载。但是,我无法弄清楚索引数据项的对齐限制是什么。引用文献
我编写了一些在 Haswell i7 处理器上运行的 AVX2 代码。相同的代码库也用于非 Haswell 处理器,其中相同的代码应替换为它们的 SSE 等效项。我想知道编译器是否有办法忽略非 Has
在英特尔内部函数指南中,vmulpd和vfmadd213pd延迟为 5,vaddpd延迟为 3。 我编写了一些测试代码,但所有结果都慢了 1 个周期。 这是我的测试代码: .CODE test_lat
在英特尔内部函数指南中,vmulpd和vfmadd213pd延迟为 5,vaddpd延迟为 3。 我编写了一些测试代码,但所有结果都慢了 1 个周期。 这是我的测试代码: .CODE test_lat
我目前正在使用 Intel Haswell RTM(事务内存的硬件支持)开发应用程序。据我所知here和 here ,建议的过程是使用某种回退锁,以防事务中止。 推荐流程如下: someTypeOfL
关闭。这个问题需要debugging details .它目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and th
我正在 haswell 中试验 tsx 扩展,通过调整现有的中型(1000 行)代码库以使用 GCC 事务内存扩展(在 native 中间接使用 haswell tsx)而不是粗粒度锁。我正在使用 G
我有以下代码(正常、SSE 和 AVX): int testSSE(const aligned_vector & ghs, const aligned_vector & lhs) { int
GCC 支持 __builtin_clz(int x) 内置函数,它计算参数中前导零(连续的最高有效零)的数量。 除其他外0,这对于有效实现 lg(unsigned int x) 非常有用函数,取 x
我正在使用 AVX 一次计算八个点积。在我当前的代码中,我做了这样的事情(在展开之前): Ivy 桥/沙桥 __m256 areg0 = _mm256_set1_ps(a[m]); for(int i
我对使用 Sandy-Bridge 和 Haswell 可以完成每个内核每个周期的触发器感到困惑。 根据我对 SSE 的理解,SSE 的每个内核每个周期应该是 4 个触发器,AVX/AVX2 的每个内
我编写了很多 punpckl、pextrd 和 pinsrd 的代码,它们旋转 8x8 字节矩阵,作为使用循环平铺旋转 B/W 图像的更大例程的一部分。 我使用 IACA 对其进行了分析,以查看是否值
我是一名优秀的程序员,十分优秀!