rdtscp 的“半栅栏”行为是怎么回事?

2023-11-22

多年来 x86 CPU 支持rdtsc指令,读取当前CPU的“时间戳计数器”。该计数器的确切定义随着时间的推移而发生变化,但在最近的 CPU 上,它是一个相对于挂钟时间以固定频率递增的计数器,因此它作为快速、准确的时钟的构建块或测量时间非常有用由小段代码获取。

关于这一点的一个重要事实rdtsc指令不以任何特殊方式与周围的代码一起排序。与大多数指令一样,它可以相对于与其不存在依赖关系的其他指令自由地重新排序。这实际上是“正常的”,对于大多数指令来说,这只是一种使 CPU 更快的几乎看不见的方式(这只是一种冗长的说法无序执行).

For rdtsc it is important because it means you might not be timing the code you expect to be timing. For example, given the following sequence1:

rdtsc
mov ecx, eax
mov rdi, [rdi]
mov rdi, [rdi]
rdtsc

你可能会期待rdtsc测量两个指针追逐加载负载的延迟mov rdi, [rdi]。然而,在实践中,即使这两个加载都需要查看时间(如果它们在缓存中丢失,则需要 100 秒的周期),您将获得相当小的读数rdtsc一对。问题是第二个rdtsc不等待加载完成,它只是无序执行,所以你没有计时你认为的时间间隔。也许两者兼而有之rdtsc指令实际上甚至在第一次加载开始之前就执行,具体取决于如何执行rdi是在本示例之前的代码中计算的。

到目前为止,这听起来更像是对一个没有人问过的问题的回答,而不是一个真正的问题,但我正在做到这一点。

您有两个基本用例rdtsc:

  • 作为一个快速时间戳,您通常不关心它如何与周围的代码重新排序,因为无论如何您可能没有关于应该在哪里获取时间戳的指令级概念。
  • 作为精确的计时机制,例如在微基准中。在这种情况下,您通常会保护您的rdtsc从重新订购lfence操作说明。对于上面的示例,您可能会执行以下操作:

    lfence
    rdtsc
    lfence
    mov ecx, eax
    ...
    lfence
    rdtsc
    

    确保定时指令(...)不要逃出计时区域之外,并且还要确保来自时间区域内部的指令不会进入(可能问题不大,但它们可能会与您想要测量的代码竞争资源)。

多年后,英特尔瞧不起我们这些可怜的程序员,想出了一条新指令:rdtscp. Like rdtsc它返回时间戳计数器的读数,并且这个家伙做了更多的事情:它使用时间戳读数原子地读取特定于核心的 MSR 值。在大多数操作系统上,这包含一个核心 ID 值。我认为这个值可以用于在每个核心可能具有不同 TSC 偏移量的 CPU 上将返回值正确调整为实时。

Great.

另一件事rdtscp介绍的是半击剑就乱序执行而言:

来自manual:

RDTSCP 指令不是序列化指令,但它确实 等待直到所有先前的指令都已执行并且所有先前的指令都已执行 负载是全局可见的。1 但它不会等待之前的存储 全局可见,后续指令可能会开始 在执行读操作之前执行。

所以这就像放一个lfence之前rdtscp,但不是之后。这种半剑的行为有什么意义呢?如果您想要一个通用时间戳并且不关心指令顺序,那么不受保护的行为就是您想要的。如果您想使用它来计时短代码部分,半围栏行为仅对第二次(最终)读取有用,但对初始读取无效,因为围栏位于“错误”一侧(实际上您想要两侧都有栅栏,但将栅栏放在内侧可能是最重要的)。

这样的半围栏有什么目的呢?


1 I'm ignoring the upper 32-bits of the counter in this case.


None

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

rdtscp 的“半栅栏”行为是怎么回事? 的相关文章

  • 主键删除需要多长时间?

    画一个简单的表结构 Table1 Table2 ID lt ID Name gt Table1ID Name Table1有几百万行 例如 350 万行 我通过主键发出删除 DELETE FROM Table1 WHERE ID 100 中
  • Visual Studio 2017 上的简单装配程序

    386 model flat c stack 100h printf PROTO arg1 Ptr Byte data msg1 byte Hello World 0Ah 0 code main proc INVOKE printf ADD
  • LockBits 性能关键代码

    我有一个方法需要尽可能快 它使用不安全的内存指针 这是我第一次尝试这种类型的编码 所以我知道它可能会更快
  • 在 Android 谷歌地图中绘制 4K 折线

    我现在正在开发一个适用于 Android 设备的应用程序 主要功能是在地图上绘制折线以显示城市中每条街道的交通情况 不幸的是 当我绘制大约 3K 折线时 数量会根据屏幕尺寸和缩放级别而减少 我的地图变得非常慢 我没有提及绘制所有线条的时间
  • 如何使用 VBA 将符号/图标格式化为单元格而不使用条件格式

    我使用 VBA 代码放置条件格式以覆盖大型表格中的值 每个单元格使用 2 个公式来确定使用 3 个符号中的哪一个 我需要根据列使用不同的单元格检查每个单元格的值 因此据我了解 我必须将条件格式规则单独放置在每个单元格上 以确保每个单元格中的
  • 奇怪的 MSC 8.0 错误:“ESP 的值未在函数调用中正确保存...”

    我们最近尝试将一些 Visual Studio 项目分解为库 并且在测试项目中一切似乎都编译和构建得很好 其中一个库项目作为依赖项 然而 尝试运行该应用程序给我们带来了以下令人讨厌的运行时错误消息 运行时检查失败 0 ESP 的值未在函数调
  • 加载实体实例需要超过 1 秒

    我在EF中遇到了一件有趣的事情 如果我们使用基础实体获取子实体 则加载实体需要更多时间 我的模型看起来像这样 public abstract class BaseDocument public Guid Id get set public
  • 数百个空闲线程的影响

    我正在考虑使用可能数百个线程来实现通过网络管理设备的任务 这是一个在带有 Linux 内核的 powerpc 处理器上运行的 C 应用程序 在每个任务进行同步以将数据从设备复制到任务的初始阶段之后 任务变得空闲 并且仅在收到警报或需要更改一
  • 尝试使用 x86 程序集 GNU GAS 在数组索引处赋值时出现错误

    我在用x86GNU 与 GCC 的程序集 并尝试实现相当于以下内容的程序集c c int x 10 x 0 5 但是 当我尝试运行 使用命令 a out 我的汇编代码如下 第一次编译后gcc filename s 错误Segmentatio
  • 从汇编程序获取命令行参数

    通读 专业汇编语言书籍 似乎它提供了用于读取命令行参数的错误代码 我纠正了一点 现在它从段错误变成了读取参数计数 然后是段错误 这是完整的代码 data output1 asciz There are d params n output2
  • 使用 AVX 内在函数代替 SSE 并不能提高速度 - 为什么?

    我已经使用 Intel 的 SSE 内在函数相当长一段时间了 并取得了良好的性能提升 因此 我希望 AVX 内在函数能够进一步加速我的程序 不幸的是 直到现在情况并非如此 可能我犯了一个愚蠢的错误 所以如果有人能帮助我 我将非常感激 我使用
  • 在未排序的整数列表中最优搜索 k 个最小值

    我刚刚接受采访时提出了一个问题 我很好奇答案应该是什么 问题本质上是 假设您有一个包含 n 个整数的未排序列表 您如何找到此列表中的 k 个最小值 也就是说 如果您有一个 10 11 24 12 13 列表并且正在寻找 2 个最小值 您将得
  • 使用循环计算 Python 字典中元素的有效方法

    我有一个值列表 我希望在循环期间计算每个类的元素数量 即 1 2 3 4 5 mylist 1 1 1 1 1 1 2 3 2 2 2 2 3 3 4 5 5 5 5 mydict dict for index in mylist mydi
  • 在 Java 中加载和缓存图像的最佳方法是什么?

    我有超过一千个 16 x 16 像素图块图像的大量集合 我在 Java 中制作的游戏需要这些图像 在不耗尽 JVM 可用内存的情况下存储切片的最佳方法是什么 我认为生成 1000 BufferedImages 可能并不明智 保持图像准备就绪
  • Python:多重分配与单独分配速度

    我一直在寻求从我的代码中挤出更多的性能 最近 在浏览时这个 Python 维基页面 https wiki python org moin PythonSpeed 我发现了这个说法 多重分配比单独分配慢 例如 x y a b 比 x a y
  • 为什么在强度降低乘法和循环进位加法之后,这段代码的执行速度会变慢?

    我正在读书阿格纳 雾 https en wikipedia org wiki Agner Fog s 优化手册 https en wikipedia org wiki Agner Fog Optimization 我遇到了这个例子 doub
  • 在 JavaScript 中嵌套“switch”案例:有速度优势吗?

    这里有新手问题 我有一个包含大量字符串的 开关 像这样按字母顺序拆分是否有速度优势 switch myString substring 0 1 case a switch myString case a string beginning w
  • Intel 64 和 IA-32 上的 MESI 有何意义

    MESI 的要点是保留共享内存系统的概念 然而 对于存储缓冲区 事情就变得复杂了 一旦数据到达 MESI 实现的缓存 下游内存就会保持一致 然而 在此之前 每个核心可能对内存位置 X 中的内容存在分歧 具体取决于每个核心的本地存储缓冲区中的
  • 有没有办法使用 i387 fsqrt 指令获得正确的舍入?

    有没有办法使用 i387 fsqrt 指令获得正确的舍入 除了改变精确模式在 x87 控制字中 我知道这是可能的 但这不是一个合理的解决方案 因为它存在令人讨厌的重入型问题 如果 sqrt 操作中断 精度模式将出错 我正在处理的问题如下 x
  • 如何知道寄存器是否是“通用寄存器”?

    我试图了解寄存器必须具备什么标准才能被称为 通用寄存器 我相信通用寄存器是一个可以用于任何用途的寄存器 用于计算 将数据移入 移出等 并且是一个没有特殊用途的寄存器 现在我读到了ESP寄存器是通用寄存器 我猜是ESP寄存器可以用于任何事情

随机推荐

  • MercurialEclipse 插件的官方/活动主页是什么?

    我找不到 MercurialEclipse 插件的官方主页 有吗 而且我有一种奇怪的感觉 实际上有多个同名的项目 以下是我发现的一些项目 http code google com a eclipselabs org p mercuriale
  • Mathjax 无法在基于 Ajax 的网页中工作

    我正在使用 Mathjax 在 PHP Ajax 完成的 Web 应用程序中显示方程 首次加载页面时 方程会正确呈现 在同一页面中 当用户单击按钮时 ajax 代码会从数据库中获取一些数据并将其显示在同一页面上 但是 方程无法正确显示 相反
  • 使用 OpenJDK 12 通过 Mockito 启动 JUnit 时如何摆脱“无法初始化插件:接口 org.mockito.plugins.MockMaker”

    我一直在将一个项目从 Java 8 迁移到 Java 12 除了单元测试之外 一切都很顺利 当我使用 Maven 编译和启动测试时 许多测试失败并显示以下消息 java lang IllegalStateException Could no
  • 从 Inherited 接口调用 Method 时,传递动态参数会引发 RuntimeBinderException

    经过一些重构后遇到了一个有趣的运行时问题 并确定了以下情况 当将属性从动态对象传递到从父接口继承的接口上的方法时 运行时绑定器无法找到该方法 这是一个演示失败和成功的测试 直接在父接口类型上调用方法时 using System Dynami
  • Selenium 2.0 WebDriver 高级交互 DoubleClick 帮助 (c#)

    因此 在我的硒回归测试中 我一直在尝试双击日历来创建新的预约 我尝试使用 doubleClick 高级用户交互库中的方法 但有一个问题 两次单击速度不够快 不够近 无法触发实际的双击 有人在测试中找到解决这个问题的方法吗 这段代码对我有用
  • 即使手机处于睡眠状态也能保持服务运行吗?

    我的应用程序中有一个服务 设计为每 10 分钟运行一次 它主要检查我们的服务器 看看一切是否正常运行 并通知用户任何问题 我创建了这个应用程序供我们公司内部使用 我的同事在长周末使用了该应用程序 并注意到设备进入睡眠状态时没有执行任何检查
  • 获取资源的大小

    我在用着getClass getResourceAsStream path 从捆绑资源中读取 在读取整个流之前如何知道文件大小 我无法访问它们getClass getResource path toURI 当它被打包时 这样就不起作用了 我
  • 如何使用Python在WebDriver中发送多个密钥?

    如何在WebDriver中制作Python代码以按键盘 或按键 上的Command Shift H按钮 Update info Pushing command to appium work queue au mainApp getTreeF
  • 在另一个目录中建立链接时符号链接不起作用?

    哇 我以前从未真正使用过符号链接 但这真的令人难以置信 bash 3 2 echo weird gt original txt bash 3 2 mkdir originals bash 3 2 mv original txt origin
  • HTTP RANGE 标头是否可与 Azure Blob 存储共享访问签名一起使用?

    我使用 Azure Blob 存储来存储媒体文件 并使用共享访问签名提供对这些文件的访问 在这方面一切进展顺利 但是 我有一个客户端应用程序需要 恢复 对这些文件的访问 并使用 HTTP RANGE 标头来执行此操作 当它发出这样的请求时
  • 无法将 WPF ListView 绑定到 ObservableCollection

    我第一次使用 WPF 特别是使用 ListView 我想将其绑定到 ObservableCollection 这是代码隐藏页面上的一个属性 现在我只是想了解一下事情是如何运作的 所以我尝试保持简单 不幸的是 我不太明白我的做法错在哪里 我的
  • Java int += double 语法惊喜[重复]

    这个问题在这里已经有答案了 我遇到了以下令人惊讶的一行 int x 7 x 0 5 显然是合法的语法 加法之后 x 仍然是 7 因此 double 被转换为 int 并向下舍入为 0 但这是在代码中没有任何显式转换的情况下完成的 还有人对此
  • 如何识别Sql Server中未命名的约束?

    动机 每当添加未命名的约束时 我都希望我们的门控签入失败 我在 Sql Server 中找不到未命名约束的任何专用名称 所以 这取决于模式匹配 我可以在 C 中完成 但模式是什么 涵盖大多数情况的最简单方法是检查 但它并不是 100 可靠
  • SpriteKit 捏合缩放相机

    我似乎无法在任何地方找到如何实现相机捏合来放大 SpriteKit 在我的 GameScene 中 我似乎无法使用以下命令在相机上运行缩放操作 let cameraNode SKCameraNode cameraNode position
  • Neo4j 匹配路径排除具有特定标签的节点

    我在检索 Neo4j 中的路径排除某些标签时遇到问题 例如 我有 gt h gt j a gt b gt c gt d gt i gt f gt g with h节点有一个Deleted label 我有疑问 MATCH path n gt
  • 尝试在 ggplot 中的直方图上应用颜色渐变

    我在 ggplot 中纠结于颜色 我正在尝试根据下面的排名列应用颜色渐变 我很确定这是颜色和填充或离散变量和连续变量之间的差异 我想要颜色如下面的 c 和 d 中的比例所示 但我最接近的尝试是 e 和 f 其中点是彩色的 但不是按渐变着色的
  • 捕获表单之外的鼠标/键盘事件(应用程序在后台运行)

    我有一个在后台运行的应用程序 最小化 任务托盘 我需要能够检测鼠标活动 点击 移动 以及键盘活动 考虑到我的窗口没有 聚焦 的限制 最好的方法是什么 看看这个图书馆全局鼠标键钩 它是 100 托管的 C 代码 用于安装全局鼠标和键盘挂钩 它
  • 将图像添加到 Pyinstaller 中的 .spec 文件

    有谁知道如何修改 spec使用创建的文件Makespec pyPyinstaller 的其中包含图像数据 MEIPASS2临时目录 我希望能够向我的 exe 添加图标 我已经完成了所写的here 但我只是不知道如何在其中添加我的数据 spe
  • 查找 HTML Canvas 上下文路径上的当前点?

    如果我有一个 HTML Canvas 上下文并且执行以下操作 ctx beginPath ctx moveTo 10 10 ctx lineTo 20 30 ctx closePath ctx stroke 在 10 10 和 20 30
  • rdtscp 的“半栅栏”行为是怎么回事?

    多年来 x86 CPU 支持rdtsc指令 读取当前CPU的 时间戳计数器 该计数器的确切定义随着时间的推移而发生变化 但在最近的 CPU 上 它是一个相对于挂钟时间以固定频率递增的计数器 因此它作为快速 准确的时钟的构建块或测量时间非常有