当前位置: 首页 > 知识库问答 >
问题:

为什么RDTSC不是序列化指令?

曹成双
2023-03-14

RDTSC 指令的英特尔手册警告说,当 RDTSC 实际执行时,无序执行可能会更改,因此他们建议在其前面插入 CPUID 指令,因为 CPUID 将序列化指令流(CPUID 永远不会无序执行)。我的问题很简单:如果他们有能力进行指令序列化,为什么他们不进行RDTSC序列化?它的全部意义似乎是获得周期准确的时间。是否存在您不希望在它之前使用序列化指令的情况?

较新的英特尔CPU有一个单独的RDTSCP指令,它正在序列化。英特尔选择引入一个单独的指令,而不是改变RDTSC的行为,这让我想到,在某些情况下,一个潜在的无序时序是你想要的。这是什么?

共有3个答案

公良鸿风
2023-03-14

他们为什么不做RDTSC序列化?它的全部目的似乎是获得周期精确计时

嗯,大部分时间是为了获取高分辨率的时间戳。至少在某些时候,这些时间戳被用于性能度量。进行指令序列化可能需要管道刷新,这对于CPU受限的应用程序来说是非常昂贵的。

英特尔选择引入一条单独的指令,而不是改变RDTSC的行为,这向我暗示,在某些情况下,可能出现的无序计时是你想要的。

改变行为几乎总是不可取的。英特尔的客户会失望地发现RDTSC在较新的部件上做了一些不同的事情。

郭翰墨
2023-03-14

如果您试图使用rdtsc来查看分支是否预测错误,则需要非序列化版本。

//math here
rdtsc
branch if zero to done
//do some work that always takes 1 cycle
done: rdtsc

如果分支预测正确,增量将很小(甚至可能为负?)。如果分支预测失误,则增量将很大。

对于序列化版本,分支条件将被解决,因为第一个rdtsc等待数学运算完成。

暴绪
2023-03-14

时间戳计数器是在奔腾微体系结构上引入的。无序执行直到Pentium Pro才出现。英特尔本可以使< code>rdtsc序列化(架构上或内部),但似乎他们决定保持它的非序列化,这对于通用时间测量是可以的,并让程序员在必要时添加序列化指令。这有利于减少测量的开销。

这在您提供的文档中得到了证实,并对奔腾和奔腾/MMX进行了以下评论(在4.2中,稍作修改):

第4.1节(奔腾Pro和奔腾II)中描述的所有规则和代码样本也适用于奔腾和奔腾/MMX。唯一的区别是,CPUID指令对于序列化不是必需的。

来自维基百科:

时间戳计数器是自奔腾以来存在于所有x86处理器上的64位寄存器。

: : :

从奔腾 Pro 开始,英特尔处理器支持无序执行,其中指令不一定按照它们在可执行文件中出现的顺序执行。这可能导致 RDTSC 的执行时间晚于预期,从而产生误导性的周期计数。

RDTSCP 的两个用途之一是除了时间戳信息之外还为您提供处理器 ID(它就在名称读取时间戳计数器 *AND* 处理器 ID 中),这在内核或插槽之间具有未同步 TSC 的系统上很有用(请参阅:如何从 C 获取x86_64 CPU 周期计数?)。rdtscp 的附加序列化属性使其在感兴趣区域的末尾更加方便(请参阅:在测量执行时间时,(rdtsc lfence rdtsc) 和 (rdtsc rdtscp) 之间是否存在任何差异?)。

 类似资料:
  • 我开始学习面向对象编程(OOP),想知道:在OOP术语中,序列化的含义是什么?

  • 我试图在Java中序列化,但在运行我的程序时,我收到一个。 查看类,我注意到它没有实现。 为什么不实现?

  • 本文向大家介绍什么是序列化与反序列化?相关面试题,主要包含被问及什么是序列化与反序列化?时的应答技巧和注意事项,需要的朋友参考一下 序列化:将对象状态转换为可保持或传输的格式的过程。将对象实例的字段及类的名称转换成字节流,然后把字节流写入数据流 反序列化:将流转换为对象。 这两个过程结合起来,可以轻松地存储和传输数据。    

  • 问题内容: 我想在特定时间获取CPU周期。我当时使用此功能: (编者注:是错的x86-64,捡起 _任何_RDX或RAX仅在32位模式下将它挑EDX:你想EAX输出中看到的。 问题是它总是返回一个 递增的 数字(每次运行)。好像是在指绝对时间。 我使用的功能不正确吗? 问题答案: 只要您的线程停留在相同的CPU内核上,RDTSC指令就会一直返回递增的数字,直到它回绕为止。对于2GHz CPU,这种

  • 如果接口只是一个标记接口,用于在 java 中传递有关类的某种元数据 - 我有点困惑: 在阅读了java的序列化算法(元数据从下到上,然后从上到下的实际实例数据)的过程之后,我无法真正理解哪些数据不能通过该算法进行处理。 简而言之: 哪些数据可能导致? 我怎么知道我不应该为我的类添加子句?

  • 问题内容: 如下代码: 引发以下异常: 我猜内部类具有一个允许对其私有访问的字段和方法的字段。声明内部类static 可以解决它,但是如果需要此访问权限怎么办?有没有一种方法可以在不包含封闭类的情况下序列化非静态内部类,例如通过引用外部类? 编辑:例如,仅在序列化之前才需要访问外部类。好的,编译器不知道这一点,但是我认为这就是关键字存在的原因。 问题答案: 如果InnerClass需要此访问权限怎