问题标签 [micro-architecture]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
performance - 在没有优化的情况下编译时添加冗余分配会加速代码
我发现一个有趣的现象:
我在i5-5257U Mac OS上使用GCC 7.3.0编译代码,没有任何优化。这是 10 次以上的平均运行时间:
还有其他人在其他英特尔平台上测试该案例并得到相同的结果。我在这里
发布 GCC 生成的程序集。两个汇编代码之间的唯一区别是,在更快的汇编代码之前还有两个操作:addl $1, -12(%rbp)
那么为什么程序在这样的分配下运行得更快呢?
彼得的回答非常有帮助。在AMD Phenom II X4 810和ARMv7 处理器 (BCM2835)上的测试显示了相反的结果,它支持存储转发加速特定于某些 Intel CPU。
BeeOnRope的评论和建议促使我重写了这个问题。:)
这个问题的核心是与处理器架构和组装有关的有趣现象。所以我认为这可能值得讨论。
x86 - 英特尔较新架构的控制指令和移动指令延迟是多少?
我正在查看英特尔架构优化参考手册 2017(第 759 页)。我正在寻找 Haswell 和 Skylake 架构。MOV, PUSH, JMP, CALL
该表中有意省略了说明。没有给出延迟信息。这是为什么?虽然,这些指令延迟是在第 776 页上针对 Atom 处理器给出的。
有趣的是,英特尔2012 年的优化手册有MOV
,PUSH
和CALL
指令延迟。
Agner 的指令表MOV
为and提供了延迟PUSH
,但跳过了像JMP
and之类的控制指令CALL
。知道为什么吗?
pipeline - 为什么有些指令需要更少的周期,而所有指令都经过相同的流水线阶段?
在处理器的说明手册中,提到一些指令需要更少的周期数,而另一些则需要更多。处理器有一个n级管道,所有指令都通过同一个管道,那么它们不应该都需要n个周期,因为每个阶段需要1个周期才能完成吗?是因为有几条指令在流水线中间开始和/或每个周期可以跳过几个阶段吗?
cpu-architecture - Zilog z80 I、R寄存器用途
Z80 cpu的Control部分有I和R寄存器,它们的用途和用途是什么?
assembly - 乱序执行如何与条件指令一起工作,例如:英特尔中的 CMOVcc 或 ARM 中的 ADDNE(加不等于)
我知道他们只能在重新排序缓冲区中的指令被提交之前正确执行。我的疑问是,现代处理器是否将它们保留到最后一个 ROB 或是否使用任何预测计数器/结构甚至用于预测标志值,例如零标志或进位标志,然后如果它们被错误预测,则重做它们
x86 - 如何使用 CPU 本身判断 x86-64 指令操作码的长度?
我知道有些库可以“解析”二进制机器码/操作码来判断 x86-64 CPU 指令的长度。
但我想知道,由于 CPU 有内部电路来确定这一点,有没有办法使用处理器本身从二进制代码中判断指令大小?(甚至可能是黑客攻击?)
c - 手臂上的阻塞矩阵mul中丢失的L1数据缓存来自哪里?
我尝试通过将整数矩阵倍数划分为更小的矩阵块来优化整数矩阵倍数,以便在 raspberry pi 3b+ 上获得更好的缓存命中率(它是 Cortex-A53 内核,具有 64 字节缓存线,4 路关联。它是 32K 字节) .
这是代码:
这是性能结果:
我在测试中将 A 设置为1024x512
和 B设置为512x1024
。并得到262144
对mat_mul
函数的调用,并且MxN
在16x8
最后调用mat_mul
.
而且我对缓存丢失的计算远小于perf的结果,这里是:
因为矩阵 A 是 16x8 而 B 是 8x16,所以 B ( 16* sizeof(int) = 64 Byte
) 的每一行都适合一个 L1 高速缓存行。现在 A 和 B 都应该适合 L1 缓存(16*8*2*sizeof(int) = 1024 Byte
我假设有 32KB 的 L1D 缓存,并且考虑到所述 4 路的关联,1024 Byte
也应该能够适合它)。因此,mat_mul
使用 A ( 16x8
) 和 B ( 8x16
) 进行的计算应该包含16 + 8 = 24
L1 缓存缺失。262,144 * 24 = 6,291,456
所以在整个计算中存在缓存缺失。
但是 perf 的结果显示存在192,979,016
缓存缺失。这30
比我预期的要多几倍。
所以我的问题是我的计算有什么问题?或者缺少的额外缓存从何而来?
而且我还使用 perf 来记录 L1 D 缓存丢失的来源,结果如下所示。if from 的 99% 缺失mat_mul
和 in 缺失的 80%mat_mul
来自最内循环的行:sum += (*Aik) * (*Bjk);
.
谢谢!
reverse-engineering - 使用 PCM 工具测量英特尔进程的 TLB 未命中惩罚
我正在尝试测量 X86-64 上的 TLB(Translation Look Aside Buffer)未命中惩罚。特别是二级统一TLB的未命中惩罚,即TLB walk的成本。
我一直在研究英特尔 pcm 工具,但无法弄清楚如何将其用于此目的。以下是我用来通过 PCM 库获取性能计数器的代码:
有了这个,我就可以获得IPC。但我不知道测试程序会如何以高精度测量 TLB 未命中惩罚。
关于我可以使用哪些其他工具进行快速估算的任何提示都会非常有帮助。
gcc - 我有哪些可用的 March/mtune 选项?
有没有办法让 gcc 输出可用的 -march=arch 选项?我遇到了构建错误(尝试过-march=x86_64
),我不知道我的选择是什么。
我正在使用的编译器是 gcc 的专有包装器,似乎不喜欢-march=skylake
. 标志应该是相同的,所以我假设我发送给 gcc 以转储架构的任何选项对于这个包装器都是相同的。
我设法使用虚假参数导致 gcc 出错,并转储了一个列表,但现在我正在通过一个包装器,我没有看到这一点。
我怎样才能让 gcc 告诉我它支持什么?
cpu-architecture - 将 mic-1 中的寄存器向右移动,无需获取
这是我第一次在这里发布问题,所以如果没有以正确的方式描述,请随时给我一些反馈。对于实际问题:
我想知道是否有一种方法可以将其中一个寄存器中的一个字向右移动 2 个字节,而无需提取或算术移位器(EX with fetch:只需将字写入内存地址 0x0 并获取 0x0 -> << 8将其复制回 OPC 或其他任何东西,然后 OR 到所需的寄存器,获取地址 0x1 并再次 OR 到寄存器,这次不向左移动)。
所以一个包含 0xcccc1111 的寄存器应该变成 0x0000cccc
以下是对 mic-1 微架构的简要说明。
谢谢您的帮助
目的是以更有效的方式将从内存 0x2 开始的单词复制到 LV 中:这应该可以工作,但它同时使用了 fetch 和 write,它可能完全是垃圾:(