- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我很难解读英特尔性能事件报告。
考虑以下主要读取/写入内存的简单程序:
#include <stdint.h>
#include <stdio.h>
volatile uint32_t a;
volatile uint32_t b;
int main() {
printf("&a=%p\n&b=%p\n", &a, &b);
for(size_t i = 0; i < 1000000000LL; i++) {
a ^= (uint32_t) i;
b += (uint32_t) i;
b ^= a;
}
return 0;
}
我用gcc -O2
编译它并在perf
下运行:
# gcc -g -O2 a.c
# perf stat -a ./a.out
&a=0x55a4bcf5f038
&b=0x55a4bcf5f034
Performance counter stats for 'system wide':
32,646.97 msec cpu-clock # 15.974 CPUs utilized
374 context-switches # 0.011 K/sec
1 cpu-migrations # 0.000 K/sec
1 page-faults # 0.000 K/sec
10,176,974,023 cycles # 0.312 GHz
13,010,322,410 instructions # 1.28 insn per cycle
1,002,214,919 branches # 30.699 M/sec
123,960 branch-misses # 0.01% of all branches
2.043727462 seconds time elapsed
# perf record -a ./a.out
&a=0x5589cc1fd038
&b=0x5589cc1fd034
[ perf record: Woken up 3 times to write data ]
[ perf record: Captured and wrote 0.997 MB perf.data (9269 samples) ]
# perf annotate
perf annotate
的结果(由我注释内存加载/存储):
Percent│ for(size_t i = 0; i < 1000000000LL; i ++) {
│ xor %eax,%eax
│ nop
│ a ^= (uint32_t) i;
│28: mov a,%edx // 32-bit load
│ xor %eax,%edx
9.74 │ mov %edx,a // 32-bit store
│ b += (uint32_t) i;
12.12 │ mov b,%edx // 32-bit load
8.79 │ add %eax,%edx
│ for(size_t i = 0; i < 1000000000LL; i ++) {
│ add $0x1,%rax
│ b += (uint32_t) i;
18.69 │ mov %edx,b // 32-bit store
│ b ^= a;
0.04 │ mov a,%ecx // 32-bit load
22.39 │ mov b,%edx // 32-bit load
8.92 │ xor %ecx,%edx
19.31 │ mov %edx,b // 32-bit store
│ for(size_t i = 0; i < 1000000000LL; i ++) {
│ cmp $0x3b9aca00,%rax
│ ↑ jne 28
│ }
│ return 0;
│ }
│ xor %eax,%eax
│ add $0x8,%rsp
│ ← retq
我的观察:
insn 每周期
我得出结论,该程序主要受内存限制。a
和 b
似乎位于同一缓存行中,彼此相邻。我的问题:
mov a,%edx
) 的 CPU 时间为零?mov a,%ecx
的时间是 0.04%,而紧邻的一个 mov b,%edx
的时间是 22.39%?<注释:
操作系统:Linux 4.19.0-amd64,CPU:Intel Core i9-9900K,100%空闲系统(也在i7-7700上测试,结果相同)。
最佳答案
不完全是“内存”限制,而是存储转发延迟的限制。 i9-9900K 和 i7-7700 每个核心的微架构完全相同,因此这并不奇怪:P https://en.wikichip.org/wiki/intel/microarchitectures/coffee_lake#Key_changes_from_Kaby_Lake 。 (除了可能改进硬件缓解 Meltdown 的方法,以及可能修复循环缓冲区 (LSD) 之外。)
请记住,当性能事件计数器溢出并触发样本时,无序超标量 CPU 必须准确选择一条正在运行的指令来“归咎”此周期
事件。通常,这是 ROB 中最旧的未退役指令,或之后的指令。对非常小规模的cycles
事件样本保持高度怀疑。
Perf 永远不会责怪产生结果缓慢的负载,通常是正在等待它的指令。 (在本例中为xor
或add
)。在这里,有时存储会消耗该异或的结果。这些不是缓存未命中加载;而是缓存未命中加载。 Skylake 上的存储转发延迟仅为大约 3 到 5 个周期(可变,如果您不尽快尝试的话会更短: Loop with function call faster than an empty loop ),因此您确实每 3 到 5 个周期完成大约 2 个负载。
内存中有两个依赖链
b
的两个 RMW。这是两倍长,并且将成为循环的整体瓶颈。a
的一个 RMW(每次迭代都有一次额外的读取,这可能与下一个 a ^= i;
的一部分的读取并行发生) .i
的 dep 链仅涉及寄存器,并且可以远远领先于其他链;毫不奇怪,add $0x1,%rax
没有计数。它的执行成本完全隐藏在等待加载的阴影中。
我有点惊讶 mov %edx,a
的计数很高。也许有时必须等待涉及 b
的旧存储 uops 在 CPU 的单个存储数据端口上运行。 (Uops按照最旧的就绪优先调度到端口。How are x86 uops scheduled, exactly?)
Uops 在之前的所有 uops 都执行完毕之前无法退出,因此它可能只是从循环底部的存储中获得一些偏差。 Uops 以 4 组为一组退出,因此如果 mov %edx,b 确实退出,则已执行的 cmp/jcc、a
的 mov 负载以及 >xor %eax,%edx
可以随之退出。这些不是等待 b
的 dep 链的一部分,因此每当 b
商店准备退出时,它们总是坐在 ROB 中等待退出。 (这是关于 mov %edx,a
如何获取计数的猜测,尽管不是真正瓶颈的一部分。)
存储地址微指令应该全部运行在循环之前,因为它们不必等待先前的迭代:RIP 相对寻址1 立即准备就绪。它们可以在端口 7 上运行,或者与端口 2 或 3 的负载竞争。对于负载也是如此:它们可以立即执行并检测它们正在等待的存储,负载缓冲区会监视它并准备好报告何时存储数据 uop 最终运行后,数据准备就绪。
大概前端最终会在分配加载缓冲区条目时遇到瓶颈,这将限制后端可以有多少微指令,而不是 ROB 或 RS 大小。
脚注 1:带注释的输出仅显示 a
而不是 a(%rip)
,所以这很奇怪;如果您以某种方式让它使用 32 位绝对值,或者只是反汇编怪癖而未能显示 RIP 相对值,这并不重要。
关于performance - `perf annotate` 内存加载/存储时间报告不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65906312/
@After public void afterScenario() { if (ScenarioManager.getScenario().isFailed()) {
我已将 BIRT 报告集成到 Grails 中并设计了一份报告。我的 grails 应用程序中有一个名为 startPeriod (仅限月份和年份)的参数,我想将其传递给 BIRT。然后 BIRT 调
我有一些 Oracle 报告 (.rdf),正在考虑将其转换为 BIRT 报告。有没有办法将 .rdf 文件转换为 BIRT 报告设计文件? 最佳答案 完全自动化的解决方案可能是不可能的。您可以部分自
当 gcc 4.1(使用 gcov)下一行: p = 新类; 报告为 100% 分支覆盖率 为什么? 因为启用了异常处理!!! 为了解决此问题,请指定: -fno-exceptions 在 g++
真的有好 免费 BugZilla 报告工具?我发现 Web 界面上的默认搜索选项太有限了。我最大的问题是缺少 Order By 选项(一次只有 1 个字段,可供选择的字段集非常有限)。我已经做了一些谷
是否可以在 CFMX7 上运行 ColdFusion Report builder 生成的报告? 更明确地说,是否可以将 CF7 中的报告生成引擎更改为 CF8? 最佳答案 我猜这可能很难做到。我记得
根据Lucintel发布的新市场报告,智能家居市场的未来看起来很有吸引力,在家用安全、家电、娱乐、照明、HVAC、医疗保健和厨房应用中将带来许多机遇。 由于COVID-19导致的全球经济衰退,
PHPCodeSniffer 是否生成 HTML 报告? 如果不是呢?怎么办? 目前,我可以运行 PHPCodeSniffer,但它只生成 XML 文件并在终端中显示结果。 如何在 phpunit 中
我在一个包中添加了一个简单的测试。 按照手册中的建议,我尝试让 PHPUnit 加载配置: phpunit -c /app phpunit.xml 看起来像这样:
我有两个从 csv 文件加载的数据框。基本上来自不同的环境但格式/列相似,它们的行/值可能有所不同。我想找到差异并在新的数据框中创建它们。两个数据框也将具有相同的顺序。我有 100 个要比较的文件。提
我想看看是否有办法通过 javadoc 在我的 junit 报告中包含“描述性文本”。 JUnit 4 似乎不像 TestNG 那样支持 @Test 注释的“描述”属性。 到目前为止,我所研究的只有一
我正在使用操作、 Controller 、servlet struts 框架编写 Excel 报告。该报告非常拥挤,已经有大约 10 个单独的查询。由于报告发生变化,我需要再添加大约 10 个查询。有
在放弃 Syleam 的 openerp jasper 模块后,我在 Nan Tic 的 jasper_reports 模块上苦苦挣扎。 它一直给我一个错误: File "C:\Program Fil
我希望创建一个简单的日历。每天由编码器生成条目计数并以日历样式查看。如一月、二月等。或按月显示全年。 database have date_added and encoder columns 我在将它
我必须为报告创建 MySQL 查询。 我有一个表history,它记录产品订单的状态更改。我有订单生命周期(订单流程)的以下状态:新、已确认、正在处理、已发货、已交付、已取消、已退回。订单不一定遵循此
如何将多个查询合并为一个? 例如: //Successful Sales: SELECT username, count(*) as TotalSales, sum(point) as Points
MySQL 优化技术的新手。请找到下面的 mysqltuner.pl 报告,并建议我应该更改 my.cnf 中的哪些变量以优化性能。 还有一个问题- 我无法在我的 my.cnf 中找到一些变量,例如
我想知道,我想将我的 Swing Worker 的某种形式的进度报告回主线程,以便我的界面可以使用随着进度增加而变化的标签进行更新,例如 checking 1/6... checking 2/6...
我正在尝试在“报告”>“销售”下运行 Magento Paypal 结算报告,但每次我尝试运行该报告时,我都会收到消息“由于配置为空,无法获取任何内容” 我查看了“系统”>“配置”>“销售”>“付款方
我想要一个工具来帮助创建 sql 查询(对于非 IT 人员),例如 dbforge。 我希望我们的非 IT 人员(例如运营)创建他们自己的 sql 查询。 我的第二个目标是让他们能够按需执行这些查询。
我是一名优秀的程序员,十分优秀!