- 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/
关闭。这个问题是opinion-based .它目前不接受答案。 想改善这个问题吗?更新问题,以便可以通过 editing this post 用事实和引文回答问题. 8年前关闭。 Improve t
暂时忘记能力的定义,只关注能力的“检查”(使用“授权!”),我看到 CanCan 添加了大约 400 毫秒,用于简单地检查用户是否具有特定的能力主题/模型。 这是预期的吗(我假设不是)?或者,有没有可
我正在阅读有关 Swift 的教程 ( http://www.raywenderlich.com/74438/swift-tutorial-a-quick-start ),它预定义为不显式设置类型,因
这主要是由于对 SQL 问题的回答。由于性能原因,有意省略了 UDF 和子查询。我没有包括可靠性并不是说它应该被视为理所当然,但代码必须工作。 性能永远是第一位的吗?提供了许多以性能为主要优先事项的答
我已经编写了一个简单的测试平台来测量三种阶乘实现的性能:基于循环的,非尾递归的和尾递归的。 Surprisingly to me the worst performant was the loop o
我已将 ui-performance 插件应用到我的应用程序中。不幸的是,在开发模式下运行应用程序时它似乎不起作用。例如,我的 javascript 导入是用“vnull”版本呈现的。 例如 不会
我有一个我操作的 F# 引用(我在各处添加对象池以回收经常创建和删除的短期对象)。我想运行结果报价;现在我使用了 F# PowerPack,它提供了将引用转换为表达式树和委托(delegate)的方法
我正在尝试在 Spark 服务器上运行 SparklyR 库中的机器学习算法。 1 个簇 8 核 24G内存 Ubuntu 16.04 星火2.2 独立配置 1名师傅/2名 worker 每个执行器的
我有一个数据库(准确地说是在 postgres 上运行),具有以下结构: user1 (schema) | - cars (table) - airplanes (table, again) .
我的应用程序在我的 iPad 上运行。但它的表现非常糟糕——我的速度低于 15fps。谁能帮我优化一下? 它基本上是一个轮子(派生自 UIView),包含 12 个按钮(派生自 UIControl)。
在完成“Scala 中的函数式编程原则”@coursera 类(class)第 3 周的作业时,我发现当我实现视频类(class)中所示的函数联合时: override def union(tha
我正在重构我的一个 Controller 以使其成为一项服务,我想知道不将整个服务容器注入(inject)我的 Controller 是否会对性能产生影响。 这样效率更高吗: innova.path.
我有一个要显示的内容很大的文件。例如在显示用户配置文件时, 中的每个 EL 表达式需要一个 userId 作为 bean 的参数,该参数取自 session 上下文。我在 xhtml 文件中将这个 u
我非常了解 mipmapping。我不明白(在硬件/驱动程序级别)是 mipmapping 如何提高应用程序的性能(至少这是经常声称的)。在执行片段着色器之前,驱动程序不知道要访问哪个 mipmap
这个问题在这里已经有了答案: 10年前关闭。 Possible Duplicate: What's the (hidden) cost of lazy val? (Scala) Scala 允许定义惰
一些文章建议现在 build() 包含在 perform() 本身中,而其他人则建议当要链接多个操作时使用 build().perform()一起。 最佳答案 build() 包含在 perform(
Postgres docs说 For best optimization results, you should label your functions with the strictest vol
阅读Zero-cost abstractions看着 Introduction to rust: a low-level language with high-level abstractions我尝
我想在 MQ 服务器上部署 SSL,但我想知道我当前的 CPU 容量是否支持 SSL。 (我没有预算增加 CPU 内核和 MQ PVU 的数量) 我的规范: Windows 2003 服务器 SP2,
因此,我在 Chrome 开发者工具 的性能 选项卡内的时间 部分成功地监控了我的 React Native 应用程序的性能。 突然在应用程序的特定重新加载时,Timings 标签丢失。 我已尝试重置
我是一名优秀的程序员,十分优秀!