rdtscp、rdtsc 之间的区别:内存和 cpuid/rdtsc?

2023-12-12

假设我们尝试使用 tsc 进行性能监控,并且我们希望防止指令重新排序。

这些是我们的选择:

1: rdtscp是一个序列化调用。它可以防止对 rdtscp 调用进行重新排序。

__asm__ __volatile__("rdtscp; "         // serializing read of tsc
                     "shl $32,%%rdx; "  // shift higher 32 bits stored in rdx up
                     "or %%rdx,%%rax"   // and or onto rax
                     : "=a"(tsc)        // output to tsc variable
                     :
                     : "%rcx", "%rdx"); // rcx and rdx are clobbered

然而,rdtscp仅适用于较新的 CPU。所以在这种情况下我们必须使用rdtsc. But rdtsc是非序列化的,因此单独使用它不会阻止CPU对其重新排序。

因此我们可以使用这两个选项之一来防止重新排序:

2:这是一个电话cpuid进而rdtsc. cpuid是一个序列化调用。

volatile int dont_remove __attribute__((unused)); // volatile to stop optimizing
unsigned tmp;
__cpuid(0, tmp, tmp, tmp, tmp);                   // cpuid is a serialising call
dont_remove = tmp;                                // prevent optimizing out cpuid

__asm__ __volatile__("rdtsc; "          // read of tsc
                     "shl $32,%%rdx; "  // shift higher 32 bits stored in rdx up
                     "or %%rdx,%%rax"   // and or onto rax
                     : "=a"(tsc)        // output to tsc
                     :
                     : "%rcx", "%rdx"); // rcx and rdx are clobbered

3:这是一个电话rdtsc with memory在破坏列表中,这可以防止重新排序

__asm__ __volatile__("rdtsc; "          // read of tsc
                     "shl $32,%%rdx; "  // shift higher 32 bits stored in rdx up
                     "or %%rdx,%%rax"   // and or onto rax
                     : "=a"(tsc)        // output to tsc
                     :
                     : "%rcx", "%rdx", "memory"); // rcx and rdx are clobbered
                                                  // memory to prevent reordering

我对第三个选项的理解如下:

拨打电话__volatile__防止优化器删除 asm 或将其移动到任何可能需要 asm 结果(或更改输入)的指令。然而,对于不相关的操作,它仍然可以移动它。所以__volatile__是不足够的。

告诉编译器内存正在被破坏:: "memory"). The "memory"clobber 意味着 GCC 无法对整个 asm 中内存内容保持不变做出任何假设,因此不会围绕它重新排序。

所以我的问题是:

  • 1:我的理解是__volatile__ and "memory"正确的?
  • 2:后两个调用做同样的事情吗?
  • 3:使用"memory"看起来比使用另一个序列化指令简单得多。为什么有人会使用第三个选项而不是第二个选项?

正如评论中提到的,a 和 a 之间存在差异编译器障碍 and a 处理器屏障. volatile and memoryasm 语句中的语句充当编译器屏障,但处理器仍然可以自由地重新排序指令。

处理器屏障是必须明确给出的特殊指令,例如rdtscp, cpuid,内存栅栏指令(mfence, lfence,...) ETC。lfence也是一个执行屏障(在英特尔上,以及最近AMD),所以结合起来很有趣rdtsc(这不是内存操作,并且仅按顺序排序*fence如果手册中有说明的话)。有趣的事实:x86 的强有序内存模型使得lfence 对于内存排序基本上没用,将执行顺序作为其主要用例。

顺便说一句,在使用时cpuid作为之前的障碍rdtsc虽然很常见,但从性能角度来看也可能非常糟糕,因为虚拟机平台经常捕获并模拟cpuid指令,以便在集群中的多台机器上施加一组通用的 CPU 功能(以确保实时迁移有效)。因此,最好使用更便宜的执行栅栏指令,例如lfence, or serialize在最近的 CPU 上(这也是一个内存屏障,并且完全序列化管道,如cpuid但没有 vmexit,所以把它放在前面rdtsc也会等待商店承诺,不像lfence只是等待指令完成执行.)

Linux内核曾经使用过mfence;rdtsc在 AMD 平台上和lfence;rdtsc关于英特尔。从 Linux 内核 5.4 开始,lfence 用于在 Intel 和 AMD 上序列化 rdtsc。请参阅此提交“x86:删除 X86_FEATURE_MFENCE_RDTSC”:https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=be261ffce6f13229dad50f59c5e491f933d3167f

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

rdtscp、rdtsc 之间的区别:内存和 cpuid/rdtsc? 的相关文章

随机推荐

  • 如何加速 VBA 宏

    我正在使用宏生成新工作表 对于新工作表生成 数据是从 4 个以上的 MS Access DB 中检索的 每个 DB 至少有 200 个字段 我的宏代码包括 1 Cell locking 2 Alignment and formatting
  • 如何在 Xamarin Forms(Android 和 iOS)中实现 Google 地图? [关闭]

    Closed 这个问题需要多问focused 目前不接受答案 我有一个 Google 地图 API 密钥 我想用它来使用 Xamarin Forms 在我的 Android 应用程序和 iOS 应用程序中显示地图 您会使用哪个库来减少两个操
  • 检查样式配置中的 IntelliJ IDEA 代码格式

    我决定为 android maven 插件做出贡献 他们使用非常特定的代码风格格式 我需要一些时间来修改IDEA代码格式规则以满足他们的要求 幸运的是有 checkstyle 配置 我已经为 IDEA 安装了检查式插件 并立即看到我当前的格
  • 如何删除 psql(PostgreSQL 交互式终端)中以常用单词开头的所有表?

    如何删除名称开头的所有表 例如doors 我可以使用某种正则表达式吗drop table命令 我不喜欢编写自定义脚本 但欢迎所有解决方案 谢谢 该脚本将生成 DDL 命令来删除它们 SELECT DROP TABLE t oid regcl
  • 在圆形数组中搜索

    在圆形数组中搜索的最佳方法是什么 Example 1 array 45 67 44 11 49 4 56 12 39 90 circular array 11 49 4 56 12 39 90 45 67 二分搜索是正确的开始方法吗 二分查
  • IntelliJ IDEA 仅运行突出显示的代码

    如何仅在 IntelliJ IDEA 中运行突出显示的代码 有时您不需要运行整个文件 而只想运行某些数量的代码 IntelliJ IDEA中有这样的选择吗 有可能计算任意表达式 Run Evaluate Expression 要评估代码片段
  • 表格大小与页面布局

    我在 Oracle Linux Server 6 3 版上使用 PostgreSQL 9 2 根据存储布局文档 页面布局包含 页头数据 24 字节 n 项 索引项 表项 的点数 AKA ItemIdData 4 字节 可用空间 n 个项目
  • Java - PaintComponent 中的 MouseListener 操作事件

    这里我有一个代码 它使用paintComponent在鼠标单击的位置上绘制一个矩形 我可以获得输出消息 但与图形和 draw 相关的任何内容都不起作用 Code import java awt import java awt event i
  • 仅解码 URL 非 ascii 字符

    现在我正在研究维基百科 在很多文章中 我注意到一些网址 例如 https www google com search q 26 E0 B8 89 E0 B8 B1 E0 B8 99 都很长 示例 URL 可以替换为 https www go
  • WPF UserControl 不继承父 DataContext

    我正在尝试开发一个可重用的用户控件 但遇到了绑定问题 我创建了一个较小的应用程序来测试它 但无法解决它 或者至少无法理解为什么它没有按照我的预期工作 代码如下 我期望的是我放在 MainWindow xaml 上的 TestUserCont
  • 转换颜色以模仿灰度打印

    读书时这个问题 我开始思考是否可以转换颜色来模仿普通的灰度打印机 假设您的屏幕已校准 找到一个可认可的近似值可以节省纸张 例如 如何转换这些颜色 看看在纸上是否可以区分浅蓝色和深蓝色和红色 temp lt rgb2hsv 239 138 9
  • 使用accepts_nested_attributes_for创建新记录或更新现有记录

    阅读重大更新以获取最新信息 嘿大家 我在 Rails 应用程序中有一个多对多关系 涉及三个表 用户表 兴趣表和连接 user interests 表 该表也有一个评级值 以便用户可以对他们的每个兴趣进行评级1 10 级 我基本上是在寻找一种
  • EF Core 5.0 - 更新 ASP.NET Core Web API 中的多对多实体

    EF Core 5 0 引入了多对多关系 我陷入了如何通过我的 asp net api 更新它们的困境 对于一对一和一对多关系 有一个约定 只需添加属性名称后跟 ID public class Blog public int BlogId
  • 找不到或无法加载程序集 mscorlib.dll

    首先 我见过这个问题 虽然问题看起来相似 但其实并不相同 我正在运行一个精简的单声道 没有使用 4 5 配置文件构建 configure with profile4 yes with profile4 5 no 我有一个针对 NET 4 0
  • Groupby 与 TimeGrouper“向后”

    我有一个DataFrame包含时间序列 rng pd date range 2016 06 01 periods 24 7 freq H ones pd Series 1 24 7 rng rdf pd DataFrame a ones 最
  • 从透明形式的图像中删除轮廓

    我正在尝试将窗口形式转换为透明 并使其仅显示一个对象 但它在我的对象周围仍然有一条线 描边 它并不像我想要的那么完美 如何取出线条 笔画 附上图片对比一下 这是我的代码 private void Form1 Load object send
  • 动态分配 UI 权限 WPF [重复]

    这个问题在这里已经有答案了 可能的重复 在代码隐藏中设置 WPF UI 权限 我开始使用 WPF 并希望创建一个应用程序 该应用程序将根据用户 AD 及其角色 自定义 显示 隐藏控件 我设法通过使用继承 MarkupExpension 和
  • 如何将 Eclipse 和 Eclipse 项目指向 Eclipse 中的新 JRE 版本? (不使用JAVA_HOME)

    设置场景 我的系统上有两个版本的 Java 有 32 位版本和 64 位版本 我拥有的另一个版本是 64 位版本的 Eclipse Java EE MyEclipse 32位版本 指的是32位版本的JDK 我现在尝试将 Eclipse 32
  • 当使用浏览器返回时,如何保留 jquery 删除的一些输入文本?

    我对以下页面有一些错误 http jsbin com agedu 带有一些注释的源代码 http jsbin com agedu edit 问题是 当输入内容并执行查询以显示搜索结果时 如果我返回浏览器中的搜索页面 Firefox 3 5
  • rdtscp、rdtsc 之间的区别:内存和 cpuid/rdtsc?

    假设我们尝试使用 tsc 进行性能监控 并且我们希望防止指令重新排序 这些是我们的选择 1 rdtscp是一个序列化调用 它可以防止对 rdtscp 调用进行重新排序 asm volatile rdtscp serializing read