标签: rdtsc

为什么RDTSC是现代处理器的虚拟化指令?

我正在研究RDTSC,并了解它是如何虚拟化虚拟机,如VirtualBox和VMWare.为什么Intel/AMD会遇到虚拟化此指令的麻烦?

我觉得它可以很容易地用陷阱来模拟它并不是一个超常用的指令(我测试过并且在禁用硬件RDTSC虚拟化的虚拟机中一般用法没有明显的减速).

但是,我知道英特尔/ AMD不会把这个指令添加到虚拟化硬件中,除非能够非常快速地执行它是很重要的.

有谁知道为什么?

hardware virtualization rdtsc

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

在Atom N450上,rdtsc的返回值为_always_ mod 10 == 0

在我的E8200机箱上,这不会发生,但是在我的Atom N450上网本(都运行OpenSuse 11.2)上,每当我读取CPU的TSC时,返回的值是mod 10 == 0,即没有被10整除的余数.我正在使用RDTSC用于测量有趣代码片段的时间的值,但为了演示的目的,我已经编写了这个小程序:

        .text
        .global _start

_start: xorl    %ebx,%ebx
        xorl    %ecx,%ecx
        xorl    %r14d,%r14d
        movb    $10,%cl
loop:   xchgq   %rcx,%r15          # save to reg
        cpuid
        rdtsc
        shlq    $32,%rdx
        xorq    %rax,%rdx          # full 64 bit of RDTSC
        movq    %r14,%r13          # save the old value
        movq    %rdx,%r14          # copy current
        movq    %r14,%rsi          #  argv[1] of printf()
        subq    %r13,%rdx          #  argv[2] (delta)
        leaq    format(%rip),%rdi  #  argv[0]
        xorl    %eax,%eax          #  no stack varargs
        call    printf
        xchgq   %rcx,%r15
        loop    loop

0:      xorl …
Run Code Online (Sandbox Code Playgroud)

x86 x86-64 intel-atom systems-programming rdtsc

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

_mm_lfence()时间开销是不确定的?

我试图确定读取元素所需的时间,以确保它是缓存命中或缓存未命中.为了阅读顺序我使用_mm_lfence()函数.我得到了意想不到的结果,经过检查后,我看到lfence函数的开销不确定.所以我正在执行程序,在例如100 000次迭代的循环中测量这种开销.我得到一次迭代的超过1000个时钟周期的结果,下次是200.这可能是lfence函数开销之间存在这种差异的原因,如果它是如此不可靠,我怎样才能正确判断缓存命中和缓存未命中的延迟?我试图使用与此帖相同的方法:使用时间戳计数器进行内存延迟测量

给出不可靠结果的代码是这样的:

for(int i=0; i < arr_size; i++){
  _mm_mfence();
  _mm_lfence();
   t1 = __rdtsc();
  _mm_lfence();
  _mm_lfence();
   t2 = __rdtsc();
  _mm_lfence();

   arr[i] = t2-t1;
}
Run Code Online (Sandbox Code Playgroud)

arr中的值在不同的范围内变化,arr_size为100 000.

c performance x86 intrinsics rdtsc

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

如何检测RDTSC是否返回恒定速率计数器值?

似乎AMD和英特尔最新的CPU都将rdtsc作为恒定速率计数器实现,避免了TurboBoost或省电设置等因频率变化引起的问题.

由于rdtsc比QueryPerformanceCounter更适合性能测量,因为它的开销要低得多,我想尽可能地使用它.

如果rdtsc是一个恒定速率计数器,我如何可靠地检测?

64-bit x86 profiling rdtsc

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

汇编程序指令:rdtsc

有人可以帮我理解https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html中给出的汇编程序

它是这样的:

uint64_t msr;
asm volatile ( "rdtsc\n\t"    // Returns the time in EDX:EAX.
               "shl $32, %%rdx\n\t"  // Shift the upper bits left.
               "or %%rdx, %0"        // 'Or' in the lower bits.
               : "=a" (msr)
               :
               : "rdx");
Run Code Online (Sandbox Code Playgroud)

它与以下内容有何不同:

uint64_t msr;
asm volatile ( "rdtsc\n\t"
               : "=a" (msr));
Run Code Online (Sandbox Code Playgroud)

为什么我们需要转移和/或操作以及rdx到底有什么作用?

编辑:添加了原始问题尚不清楚的内容.

  • 什么"\n\t"做什么?
  • ":"做什么?
    • 分隔符输出/输入/ clobbers ...
  • rdx末尾是否等于0?

回顾一下.第一行加载寄存器eax和edx中的时间戳.第二行将eax中的值移位并存储在rdx中.第三行将edx中的值与rdx中的值一起使用,并将其保存在rdx中.第四行将rdx中的值赋给我的变量.最后一行将rdx设置为0.

  • 为什么前三行没有":"?
    • 他们是一个模板.输出带有":"的第一行,第二行是可选输入,第三行是clobbers的可选列表(已更改的寄存器).
  • 实际上是eax和d - edx吗?这是硬编码的吗?

再次感谢!:)

EDIT2:回答了我的一些问题......

x86 assembly gcc timestamp rdtsc

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

如何保证RDTSC是准确的?

我读过 RDTSC 可以给出错误的读数,不应依赖。
这是真的吗?如果是这样,可以做些什么?

x86 x86-64 rdtsc cpuid

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

使用rdtsc计算系统时间

假设我的CPU中的所有内核具有相同的频率,从技术上讲,我可以每毫秒左右为每个内核同步系统时间和时间戳计数器对.然后根据我正在运行的当前核心,我可以获取当前rdtsc值并使用tick delta除以核心频率,我能够估计自上次同步系统时间和时间戳计数器对后经过的时间.推断当前系统时间而没有来自当前线程的系统调用开销(假设不需要锁来检索上述数据).这在理论上很有效,但在实践中我发现有时我会得到更多的滴答,然后我会期望,也就是说,如果我的核心频率为1GHz并且我花了1毫秒的系统时间和时间戳计数器对,我希望看到一个delta在大约10 ^ 6个刻度的刻度线中,但实际上我发现它可以在10 ^ 6到10 ^ 7之间的任何位置.我不确定有什么问题,有人可以分享他对如何计算系统时间的看法rdtsc吗?我的主要目标是避免每次我想知道系统时间时执行系统调用的需要,并且能够在用户空间中执行计算,这将给我一个很好的估计(目前我定义了一个很好的估计结果)与实际系统时间间隔为10微秒.

c++ time assembly rdtsc

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

不同的进程可以同时运行RDTSC吗?

不同的进程可以同时运行RDTSC吗?还是这是只有一个内核可以同时运行的资源?TSC位于每个内核中(至少您可以针对每个内核分别进行调整),因此应该可行。但是超级跑步呢?

我该如何测试?

x86 multicore intel hyperthreading rdtsc

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

多个 nop 指令并不总是比单个 nop 指令花费更长的时间

我使用 C++ 对多个 NOP 指令和单个 NOP 指令进行计时rdtsc。但是,我没有发现执行 NOP 所需的周期数与执行的 NOP 数成正比。我很困惑为什么会出现这种情况。我的 CPU 是 Intel Core i7-5600U @ 2.60Ghz。

这是代码:

#include <stdio.h>

int main() {
    unsigned long long t;

    t = __rdtsc();
    asm volatile("nop");
    t = __rdtsc() - t;
    printf("rdtsc for one NOP: %llu\n", t);

    t = __rdtsc();
    asm volatile("nop; nop; nop; nop; nop; nop; nop;");
    t = __rdtsc() - t;
    printf("rdtsc for seven NOPs: %llu\n", t);

}
Run Code Online (Sandbox Code Playgroud)

我得到的值如下:

rdtsc for one NOP: 78
rdtsc for seven NOPs: 91 …
Run Code Online (Sandbox Code Playgroud)

assembly processor inline-assembly rdtsc no-op

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

恒定非不变 tsc 可以改变 CPU 状态的频率吗?

我曾经使用 rdtsc 对 Linux 系统调用进行基准测试,以获取系统调用前后的计数器差异。我将结果解释为挂钟定时器,因为 TSC 以恒定速率递增,并且在进入暂停状态时不会停止。

不变 TSC 概念描述为

不变的 TSC 将在所有 ACPI P-、C- 中以恒定速率运行。和 T 状态。

当状态从 C0(运行)更改为 C1(停止)时,恒定非不变tsc 是否可以改变频率?

我当前的观点是,它不能仅在性能(P)状态下更改频率。因此,在使用非不变 tsc 时,应用 rdtsc 获取用于系统调用的挂钟计时器并不可靠。

我在 my 中没有找到不变的 tsc 标志/proc/cpuinfo,只是constant_tsc意味着它没有必要不变

混乱的根源是英特尔系统编程手册中的一句话:

较新处理器中的时间戳计数器可能支持增强功能,称为不变 TSC。

所以有些芯片(包括我的)具有恒定的 tsc,但不是不变的。

assembly x86-64 intel cpu-architecture rdtsc

3
推荐指数
1
解决办法
2906
查看次数