小编Had*_*ais的帖子

了解CYCLE_ACTIVITY.*Haswell性能监控事件

我试图分析英特尔Haswell的CPU(英特尔®酷睿™i7-4900MQ)与自上而下的微架构分析方法(TMAM),在各章B.1和B.4所述,在执行英特尔®64和IA-32架构优化参考手册.(如果需要,我将B.4中描述的Sandy Bridge公式调整为Haswell Microarchitecture.)

因此,我使用Perf执行性能计数器事件测量.有些结果我不明白:

  1. CPU_CLK_UNHALTED.THREAD_P < CYCLE_ACTIVITY.CYCLES_LDM_PENDING

这仅适用于少数测量,但仍然很奇怪.PMU计数是否会停止CYCLE_ACTIVITY.CYCLES_LDM_PENDING

  1. CYCLE_ACTIVITY.CYCLES_L2_PENDING> CYCLE_ACTIVITY.CYCLES_L1D_PENDINGCYCLE_ACTIVITY.STALLS_L2_PENDING>CYCLE_ACTIVITY.STALLS_L1D_PENDING

这适用于所有测量.当L1D高速缓存未命中时,负载会转移到L2高速缓存,对吧?因此早先错过L2的负载也错过了L1.这里没有计算L1指令高速缓存,但是它的大小*_L2_PENDING是100倍甚至1000倍*_L1D_PENDING,可能不是这样.是否分别以某种方式测量了档位/周期?但是有这个公式:

%L2_Bound = (CYCLE_ACTIVITY.STALLS_L1D_PENDING - CYCLE_ACTIVITY.STALLS_L2_PENDING) / CLOCKS

因此CYCLE_ACTIVITY.STALLS_L2_PENDING< CYCLE_ACTIVITY.STALLS_L1D_PENDING假定(公式的结果必须为正).(这个公式的另一个原因是它可能应该CYCLES代替STALLS.但是这不能解决上面描述的问题.)那么如何解释呢?

编辑:我的操作系统:Ubuntu 14.04.3 LTS,内核:3.13.0-65-通用x86_64,性能版本:3.13.11-ckt26

intel performancecounter cpu-architecture cpu-cache perf

5
推荐指数
1
解决办法
635
查看次数

PERF STAT不计算内存负载,但计算内存存储

Linux内核:4.10.0-20-generic(也在4.11.3上试过)

Ubuntu:17.04

我一直试图使用收集内存访问的统计信息perf stat.我能够收集内存存储的统计信息,但内存加载的计数返回0值.

以下是内存存储的详细信息: -

perf stat -e cpu/mem-stores/u ./libquantum_base.arnab 100
N = 100, 37 qubits required
Random seed: 33
Measured 3277 (0.200012), fractional approximation is 1/5.
Odd denominator, trying to expand by 2.
Possible period is 10.
100 = 4 * 25

 Performance counter stats for './libquantum_base.arnab 100':

       158,115,510      cpu/mem-stores/u                                            

       0.559922797 seconds time elapsed
Run Code Online (Sandbox Code Playgroud)

对于内存加载,我得到0计数,如下所示: -

perf stat -e cpu/mem-loads/u ./libquantum_base.arnab 100
N = 100, 37 qubits required
Random seed: …
Run Code Online (Sandbox Code Playgroud)

linux x86 intel perf

5
推荐指数
1
解决办法
865
查看次数

即使 RS 未完全充满,RESOURCE_STALLS.RS 事件是否也可能发生?

RESOURCE_STALLS.RSIntel Broadwell 硬件性能事件的描述如下:

此事件对由于保留站 (RS) 中缺少合格条目而导致的停顿周期进行计数。这可能是由于 RS 溢出,或由于 RS 阵列写入端口分配方案导致的 RS 解除分配(每个 RS 条目有两个写入端口而不是四个。因此,无法使用空条目,尽管 RS 并未真正满) . 这计算管道后端阻止来自前端的 uop 传递的周期。

这基本上说有两种情况会发生 RS 停顿事件:

  • 当RS 的所有符合条件的条目都被占用并且分配器没有停止时。
  • 当因为只有两个写端口而发生“RS 解除分配”时,并且分配器没有停止。

在第一种情况下,“合格”是什么意思?这是否意味着并非所有条目都可以被各种 uop 占用?因为我的理解是,在现代微体系结构中,任何条目都可以被任何类型的 uop 使用。还有什么是 RS 阵列写入端口分配方案,即使并非所有条目都被占用,它如何导致 RS 停顿?这是否意味着 Haswell 中有四个写端口,而现在 Broadwell 中只有两个?即使手册没有明确说明,这两种情况是否适用于 Skylake 或 Haswell?

performance x86 intel cpu-architecture intel-pmu

5
推荐指数
1
解决办法
344
查看次数

子进程退出后内核复制CoW页面

在Linux中,只要分支了一个进程,父进程的内存映射就会被克隆到子进程中。实际上,出于性能原因,这些页面被设置为写时复制 -最初它们是共享的,并且如果两个进程之一在其中之一上进行写操作,则将其克隆MAP_PRIVATE)。

这是获取正在运行的程序状态的快照的一种非常常见的机制-您进行了分叉,这使您可以在该时间点(一致)查看进程的内存。

我做了一个简单的基准测试,其中包含两个部分:

  • 父进程具有线程池写入到一个数组
  • 一个具有线程池的子进程,该线程池为阵列创建快照并取消映射

在某些情况下(机器/体系结构/内存位置/线程数/ ...),我能够比线程写入数组早得多地完成复制。

但是,当子进程退出时,htop我仍然可以看到大部分CPU时间都花在了内核上,这与它在父进程写入页面时用于处理复制是一致的。

以我的理解,如果标记为写时复制的匿名页面是由单个进程映射的,则不应复制该页面,而应直接使用它。

我如何确定这确实是在复制内存上花费的时间?

如果我是对的,如何避免这种开销?


现代 C ++ 中,基准测试的核心如下。

定义WITH_FORK以启用快照;保留undefined可禁用子进程。

#include <unistd.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/wait.h>

#include <numaif.h>
#include <numa.h>

#include <algorithm>
#include <cassert>
#include <condition_variable>
#include <mutex>
#include <iomanip>
#include <iostream>
#include <cmath>
#include <numeric>
#include <thread>
#include <vector>

#define ARRAY_SIZE 1073741824 // 1GB …
Run Code Online (Sandbox Code Playgroud)

c++ memory performance copy-on-write linux-kernel

5
推荐指数
1
解决办法
132
查看次数

当线程调度在不同的 CPU 核心上时,预期的内存语义(例如写入后读取)会发生什么情况?

单线程内的代码具有一定的内存保证,例如先读后写(即将一些值写入内存位置,然后读回它应该给出您写入的值)。

如果线程被重新安排在不同的 CPU 核心上执行,这样的内存保证会发生什么?假设一个线程将 10 写入内存位置 X,然后重新调度到不同的核心。该核心的 L1 缓存可能具有不同的 X 值(与之前在该核心上执行的另一个线程不同),因此现在读取 X 不会像线程期望的那样返回 10。当线程被调度到不同的核心上时,是否会发生一些 L1 缓存同步?

multithreading operating-system cpu-architecture memory-barriers cpu-cache

5
推荐指数
1
解决办法
471
查看次数

为什么不预测两个分支?

CPU使用分支预测来加速代码,但仅限于实际采用第一个分支.

为什么不简单地采取两个分支?也就是说,假设两个分支都将被命中,缓存两侧,并在必要时采取适当的分支.缓存不需要无效.虽然这需要编译器预先加载两个分支(更多的内存,适当的布局等),但我认为适当的优化可以简化两者,以便可以从单个预测器获得接近最优的结果.也就是说,需要更多的内存来加载两个分支(对于N个分支是指数的),大多数时候应该能够在完成执行分支之前足够快地用新代码"重新缓存"失败的分支. .

if(x)Bl else Br;

不假设采用Bl,而是假设采用Bl和Br(某种类型的并行处理或特殊交织),并且在实际确定分支之后,一个分支随后无效,然后可以释放缓存以供使用(可能是一些需要特殊技术的类型才能正确填写和使用它.

实际上,不需要预测电路,并且所有用于此的设计可以用于处理两个分支.

任何想法,如果这是可行的?

cpu cpu-architecture prefetch speculative-execution branch-prediction

4
推荐指数
1
解决办法
584
查看次数

用于英特尔处理器的TLB ASID标签中有多少位?以及如何处理“ ASID溢出”?

根据一些操作系统的教科书,为了更快地进行上下文切换,人们在TLB标签字段中为每个进程添加了ASID,因此我们不需要在上下文切换中刷新整个TLB。

我听说有些ARM处理器和MIPS处理器在TLB中确实具有ASID。但是我不确定Intel x86处理器是否具有ASID。

同时,似乎ASID通常具有比PID(32位)少的位(例如8位)。那么,如果在上述8位ASID情况下内存中的进程比2 ^ 8多,那么系统如何处理“ ASID溢出”?

x86 operating-system intel virtual-memory tlb

4
推荐指数
1
解决办法
400
查看次数

为什么在全关联 TLB 中 LRU 实现成本高昂?

我有一本书的声明:

在全关联 TLB 中实现 LRU 非常昂贵,所以一般的方法是使用随机替换。

我不明白为什么在完整的关联缓存下它很昂贵。这不就是增加了一个额外的参考位......?

cpu-architecture tlb cpu-cache

4
推荐指数
1
解决办法
607
查看次数

在硬件中断之前如何处理分支错误预测

特定向量(未屏蔽)发生硬件中断,CPU 检查 IF 标志并将 RFLAGS、CS 和 RIP 压入堆栈,同时后端仍有指令完成,其中一条指令的分支预测结果是错误的。通常管道会被刷新,前端开始从正确的地址获取,但在这种情况下,中断正在进行中。

当中断发生时,流水线中的指令会发生什么情况?

我已经读过这篇文章,显然解决方案是立即刷新管道中的所有内容,这样就不会发生这种情况,然后生成指令将 RFLAGS、CS、RIP 推送到 TSS 中内核堆栈的位置;然而,问题出现了,它如何知道与最新架构状态关联的 (CS:)RIP,以便能够将其推送到堆栈上(假设前端 RIP 现在将领先)。这类似于 port0 上的采取分支执行单元如何知道当采取预测结果错误时应该获取的 (CS:)RIP 的问题——是编码到指令中的地址以及预言?当你想到陷阱/异常时,也会出现同样的问题,CPU需要将当前指令(故障)或下一条指令(陷阱)的地址推送到内核堆栈,但是它是如何计算出这条指令的地址的当它处于管道的中途时——这让我相信地址必须被编码到指令中并使用长度信息计算出来,这可能全部在预解码阶段完成。

pipeline intel cpu-architecture interrupt-handling branch-prediction

4
推荐指数
1
解决办法
1067
查看次数

Perf 事件:dTLB 加载和 dTLB 存储的含义是什么?

我试图理解性能事件的含义:dTLB 加载和 dTLB 存储?

intel tlb perf amd-processor

4
推荐指数
2
解决办法
3349
查看次数