问题标签 [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.
x86 - 指令的执行过程和在gem5中的实现?
我正在学习gem5上程序的运行过程。并且读了一些书。但是我仍然对程序执行中的部分感到困惑。我下面的理解正确吗?
- 首先将计算机指令放入ICache,由计算机CPU控制指令的取指,将取指的指令放入指令队列。然后从指令队列中取出指令,将指令解码为微操作. 这些微操作将被发送到重新排序缓冲区。如果重新排序缓冲区中的微操作是加载/存储,则将其发送到加载/存储队列。如果是加减法等运算,则直接发送给执行单元。在这个过程中,每个执行单元都有一个保留站用于寄存器重命名。微操作完成后,会返回reorder buffer。当微操作到达reorder buffer的头部时,可以将其写回Cache或CPU外的内存中。
- 加载队列将从缓存中获取数据。缓存一般是虚拟地址索引和物理地址标签。加载操作将并行从缓存中获取并执行虚拟地址转换。如果 Cache 未命中,加载操作将被发送到 MSHR。MSHR 将获取的数据发送到内存。如果数据在内存中,则先将数据取到Cache中,再将取到的数据返回到MSHR,再返回到加载队列。如果数据不在内存中,操作系统会发出缺页,然后将数据从硬盘中取出到内存中,从Cache中取出,然后返回到MSHR,再返回到加载队列。
问题:
- 微操作是指解码时的mov、add等操作吗?
- 指令发出是指发送到重排序缓冲区还是从重排序缓冲区发送到执行单元的微操作?指令解码后,是直接送到reorder buffer吗?
- dispatch 和 issue 指的是同一个过程吗?
- 我还看到了一些队列,例如浮点数队列或其他队列。这是指指令从reorder buffer发送到执行单元时,由于执行单元不足而临时存放指令的地方吗?这些队列与 Tomasulo 算法中的预约站指的是同一个东西吗?
mips - 这种多周期 MIPS 能否避免新 PC 值的多路复用?
我遇到了这个多周期 MIPS 处理器微架构。我的疑问是,真的需要选择 PC 值的多路复用器(由 PCSrc 选择)吗?仅将时钟 PC 值发送到 PC 有什么危害?
考虑到指令是 lw、sw、beq 或 ALU 操作,第二个周期将用于从寄存器文件中获取操作数。该周期可用于翻转 PC 值,而不是使用第一个周期来更新 PC 值。这将节省一个多路复用器。
请告诉我我的理解是否正确。
x86-64 - x86 中的缓存块替换策略是否更喜欢干净块而不是脏块?
x86 系统中的缓存块替换策略是否更喜欢干净块而不是脏块?我很想知道缓存行刷新指令是否会clwb
影响缓存替换策略,因为clwb
在缓存中保持块处于干净状态。
assembly - 如何通过操作码或反汇编查找使用了何种形式的指令?
https://uops.info/和 Agner Fog 的指令表等网站,甚至英特尔自己的手册,都列出了同一指令的各种形式。例如add m, r
(在 Agner 的表格中)或add (m64, r64)
在 uops.info 上,或ADD r/m64, r64
在英特尔的手册中 ( https://www.felixcloutier.com/x86/add )。
这是我在 Godbolt 上运行的一个简单示例
添加的是add DWORD PTR fs:0xfffffffffffffffc,0x5
. 它从操作码开始64 83 04 25
。
有几种方法可以编写我的真实代码,但我想查找这可能需要多少个周期以及其他信息。我怎么能找到对这个指令的引用?我尝试在https://uops.info/table.html中输入“添加”并检查我的架构。但我不知道哪个条目是正在使用的指令。
现在在这种特定情况下,我猜测操作码是Add m64, r64但我不知道fs:
在地址之前使用是否有任何惩罚,或者是否有办法查看操作码,所以我可以确认我正在查看正确的参考
caching - write-invalidate 策略如何与 set-associative 缓存一起工作?
我正在阅读Norman P. Jouppi 的Cache Write Policies论文,我理解为什么 write-invalidate(在第 193 页定义)适用于直接映射缓存,这是因为能够写入检查标签的数据,如果发现如果未命中,则缓存行无效,因为它已被写入损坏。这可以在一个周期内完成。但是,如果将 write-invalidate 用于 set-associative 缓存有什么好处吗?实际处理器中用于 L1 缓存的通常配置是什么?他们是否使用直接或设置关联和写验证/写周围/写无效/写时获取策略?
caching - 多级缓存中的一致性如何实现?
我已经了解缓存一致性 FSM 如何适用于单个私有 L1 缓存和公共 LLC/内存。但是当有 2 个私有缓存 - L1 和 L2 以及一个公共内存时,他们无法找到讨论缓存一致性的好资源。我不明白互连网络在整个模型中的位置,L1缓存snoop及其FSM是什么。
queue - 在 MSHR 存在的情况下,Load Store Queue 是如何工作的?
我了解加载存储队列的基本工作原理,即
- 当负载计算它们的地址时,它们会检查存储队列中是否存在相同地址的任何先前存储,如果有,则它们从最近的存储中获取数据,否则从写入缓冲区或数据缓存中获取。
- 当商店计算他们的地址时,他们检查加载队列是否有任何加载违规
我的疑问是当
在第一种情况下,由于存储队列中的一些未解析的存储地址而导致加载访问数据缓存,并且在 L1 数据缓存中访问未命中,并且在可以从缓存中检索数据之前,存储地址已解析。现在,商店确实加载队列检查是否有任何违规行为。从属负载之前已经访问过数据缓存,但由于长时间未命中,尚未从缓存中接收到值。商店是发布加载违规还是进行存储到加载转发并从缓存中取消数据?
当 l1 数据缓存中的加载访问未命中时,加载将放置在 MSHR 中,以免阻塞执行阶段。当未命中解决时,该加载的 MSHR 条目具有有关目标寄存器和物理地址的信息。所以这个值可以在物理寄存器中更新,但是 MSHR 如何与加载队列通信以得知该值可用?这在管道阶段何时发生?因为我在某处读过 MSHR 存储物理地址和 Load-store 队列存储虚拟地址。那么 MSHR 是如何与 LSQ 通信的呢?
我还没有找到任何关于这些疑问的资源。
x86 - 在什么情况下会触发基于 L1 IP 的跨步预取器?
Intel 硬件预取器 Intel 网站显示有四种硬件预取器。位 3 控制的预取器是 L1 步长预取器。我正在运行一个测试代码来测试步幅预取器的触发条件是什么。我使用以下步骤运行代码(将 MSR0x1a4 设置为 0x7,这意味着仅启用基于 L1 IP 的 strider 预取器):
我希望看到第 12 行被预取到缓存中。但是我只能看到缓存中的第 0 3 6 9 行被命中。即使在我更改步幅或访问模式的长度后,也无法观察到步幅预取活动。所以我想知道是否有人在英特尔处理器中看到过预取活动,或者有一些我没有注意到的特殊触发条件?
对此案例感兴趣的朋友可以试一下测试代码,运行即可sudo ./run.sh
。我机器上的结果显示第 12 行的访问时间大多大于 180 个周期。我认为时间测量代码没有问题,因为如果我将测量的行从缓存行 12 更改为缓存行 6(只需在 test.c,第 103 行更改它),那么访问时间主要是 25 个周期。
intel - 如何找出 CPU 中禁用的内核?
我需要找出 CPU 上禁用了哪些内核。如何以 C/C++ 方式执行此操作?我知道读取 CAPID6 寄存器是其中一种方法,但我不确定如何完成它。我需要注意任何系统调用或技巧吗?
我的操作系统是 Ubuntu。我有 Xeon Skylake CPU。我可以通过检查 /sys/devices/system/cpu/cpu*/online 来查看特定内核是脱机还是联机,以查看文件是否包含 0 或 1,分别表示脱机或联机。
我还检查了下面的链接:
我理解 John McCalpin 的回答,但我再次在寻找一种 C/C++ 方式来做到这一点。