标签: rdtsc

时间戳计数器

我通过查询寄存器在我的 C++ 程序中使用时间戳计数器。但是,我遇到的一个问题是获取时间戳的函数会从不同的 CPU 获取。我怎样才能确保我的函数总是从同一个 CPU 获取时间戳,或者无论如何都可以同步 CPU?顺便说一下,我的程序在 Fedora 13 64 位的 4 核服务器上运行。

谢谢。

linux rdtsc

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

为什么第一个printf需要更长的时间?

我正在玩高精度计时器,我的第一个测试之一是使用rdtsc来测量printf.下面是我的测试程序,然后输出.我注意到的是,第一次printf运行时,它在第一次打印时总是比在后续打印时长约25倍.这是为什么?

#include <stdio.h>
#include <stdint.h>

// Sample code grabbed from wikipedia
__inline__ uint64_t rdtsc(void)
{
    uint32_t lo, hi;
    __asm__ __volatile__ (
            "xorl %%eax,%%eax \n        cpuid"
            ::: "%rax", "%rbx", "%rcx", "%rdx");
    __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
    return (uint64_t)hi << 32 | lo;
}

int main(int argc, const char *argv[])
{
    unsigned int i;
    uint64_t counter[10];
    uint64_t sum = 0;
    for (i = 0; i < 10; i++)
    {
        counter[i] = rdtsc();
        printf("Hello, world\n");
        counter[i] = rdtsc() - counter[i]; …
Run Code Online (Sandbox Code Playgroud)

c printf rdtsc

3
推荐指数
2
解决办法
752
查看次数

在Assembly中使用rdtsc函数

我试图使用Ubuntu 12.04配置x86汇编程序.我想使用rdtsc函数.问题是,根据评论,我应该得到rdx中的周期数,但是使用下面的代码我得到一个太高的数字:

SECTION .bss

SECTION .dat

SECTION .text


global main         

main:           
nop

cpuid
rdtsc
shl rdx, 32
or rdx, rax
mov r8, rdx

xor esi,esi
mov esi,19        ; instructions to be monitored


cpuid
rdtsc
shl rdx, 32
or rdx, rax
sub rdx, r8
Run Code Online (Sandbox Code Playgroud)

在调试器中运行它我在子指令后的寄存器上得到以下结果:

rax     0xd88102bc
rbx     0x0
rcx     0xf0
rdx     0x44f3914a0
rsi     0x13
rdi     0x1
rbp     0x0
rsp     0x7fffffffdf38
r8      0x11828947ee1c
Run Code Online (Sandbox Code Playgroud)

我无法弄清楚为什么rdx中的循环次数如此之高以至于这么简单的指令.rcx中的数字是正确的吗?是不是太高了?

提前致谢

assembly profiling rdtsc

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

如何将此汇编时间戳函数转换为C++?

我试图将别人的项目从32位转换为64位.除了一个函数外,一切似乎都没问题,它使用了构建x64时Visual Studio不支持的汇编表达式:

// Returns the Read Time Stamp Counter of the CPU
// The instruction returns in registers EDX:EAX the count of ticks from processor reset.
// Added in Pentium. Opcode: 0F 31.
int64_t CDiffieHellman::GetRTSC( void )
{
    int tmp1 = 0;
    int tmp2 = 0;

#if defined(WIN32)
    __asm
    {
        RDTSC;          // Clock cycles since CPU started
        mov tmp1, eax;
        mov tmp2, edx;
    }
#else
    asm( "RDTSC;\n\t"
        "movl %%eax, %0;\n\t"
        "movl %%edx, %1;" 
        :"=r"(tmp1),"=r"(tmp2)
        :
        :
        );
#endif

    return ((int64_t)tmp1 …
Run Code Online (Sandbox Code Playgroud)

c++ inline-assembly rdtsc

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

NASM中的RDTSCP始终返回相同的值

我正在NASM中使用RDTSC和RDTSCP测量各种汇编语言指令的机器周期,以帮助优化。

我读了Intel的Gabriele Paoloni撰写的“如何在Intel IA-32和IA-64指令集体系结构上对代码执行时间进行基准测试”(2010年9月)和其他Web资源(其中大多数是C语言中的示例)。

使用下面的代码(从C转换),我测试了各种指令,但RDTSCP在RDX中始终返回零,在RAX中始终返回7。我首先认为7是周期数,但显然并非所有指令都需要7个周期。

rdtsc
cpuid
addsd xmm14,xmm1 ; Instruction to time
rdtscp
cpuid
Run Code Online (Sandbox Code Playgroud)

返回7,这并不奇怪,因为在某些体系结构上,添加了7个周期(包括延迟)。前两个指令(根据某些情况)可以颠倒,先是cpuid,然后是rdtsc,但这在这里没有什么区别。

当我将指令更改为2周期指令时:

rdtsc
cpuid
add rcx,rdx ; Instruction to time
rdtscp
cpuid
Run Code Online (Sandbox Code Playgroud)

这还会在rax中返回7,在rdx中返回零。

所以我的问题是:

  1. 如何访问和解释RDX:RAX中返回的值?

  2. 为什么RDX总是返回零,应该返回什么?

更新:

如果我将代码更改为此:

cpuid
rdtsc
mov [start_time],rax
addsd xmm14,xmm1 ; INSTRUCTION
rdtscp
mov [end_time],rax
cpuid
mov rax,[end_time]
mov rdx,[start_time]
sub rax,rdx
Run Code Online (Sandbox Code Playgroud)

我的rax达到了64,但这听起来像是周期太多。

optimization x86-64 nasm rdtsc windows64

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

“ rdtsc”:“ = a”(a0),“ = d”(d0)这是做什么的?

我是C ++和基准测试的新手

我不明白这段代码的作用是什么?因此,我找到了一些有关edx,eax寄存器的信息,但是我不完全了解它如何在代码中发挥作用。所以我理解这段代码本质上返回了cpu周期的当前滴答声。因此,它是否将当前的滴答存储在寄存器中,一部分存储在hi中,另一部分存储在lo中。并且,“ = a”和“ = d”是否指定将其存储在哪个寄存器中。

将其分为两个部分的意义何在?

"rdtsc" : "=a" (lo), "=d" (hi) 
Run Code Online (Sandbox Code Playgroud)

上下文中的代码:

int64_t rdtsc(){
    unsigned int lo,hi;
    __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
    return ((uint64_t)hi << 32) | lo;
}
Run Code Online (Sandbox Code Playgroud)

c++ x86 gcc inline-assembly rdtsc

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

Is there any difference in between (rdtsc + lfence + rdtsc) and (rdtsc + rdtscp) in measuring execution time?

As far as I know, the main difference in runtime ordering in a processor with respect to rdtsc and rdtscp instruction is that whether the execution waits until all previous instructions are executed locally.

In other words, it means lfence + rdtsc = rdtscp because lfence preceding the rdtsc instruction makes the following rdtsc to be executed after all previous instruction finish locally.

However, I've seen some example code that uses rdtsc at the start of measurement and rdtscp at …

x86 assembly cpu-architecture microbenchmark rdtsc

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

RDTSCP 是否跨多核单调递增?

我很困惑rdtscp在多核环境中是否单调递增。根据文档:__rdtscprdtscp似乎是基于处理器的指令,可以防止围绕调用重新排序指令。

处理器在每个时钟周期单调递增时间戳计数器 MSR,并在处理器复位时将其复位为 0。

rdtscp肯定会在同一个 CPU 内核上单调递增,但是这个rdtscp时间戳是否保证在不同的 CPU 内核上是单调的?我相信没有这种绝对的保证。例如,

Thread on CPU core#0                   Thread on CPU core#1

unsigned int ui;
uint64_t t11 = __rdtscp(&ui); 
uint64_t t12 = __rdtscp(&ui);  
uint64_t t13 = __rdtscp(&ui);         
                                       unsigned int ui;
                                       uint64_t t21 = __rdtscp(&ui);
                                       uint64_t t22 = __rdtscp(&ui);
                                       uint64_t t23 = __rdtscp(&ui);
Run Code Online (Sandbox Code Playgroud)

以我的理解,我们可以有一个决定性的结论t13 > t12 > t11,但我们不能保证t21 > t13

我想写一个脚本来测试我的理解是否正确,但我不知道如何构建一个例子来验证我的假设。

// file name: rdtscptest.cpp
// g++ rdtscptest.cpp -g -lpthread -Wall -O0 -o …
Run Code Online (Sandbox Code Playgroud)

c++ x86 assembly multicore rdtsc

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

是否有比cpuid更便宜的序列化指令?

我已经看到了相关的问题,包括这里这里,但似乎有关序列化的唯一指令rdtsccpuid.

不幸的是,cpuid我的系统需要大约1000个周期,所以我想知道是否有人知道更便宜(更少的周期和没有读或写内存)序列化指令?

我看着iret,但这似乎改变了控制流程,这也是不可取的.

我实际上看过亚历克斯的答案中关联的白纸rstscp,但它说:

在读取计数器之前,RDTSCP指令等待直到执行了所有先前的指令.然而,后续指令可以在执行读取操作之前开始执行.

第二点似乎是让它不理想.

intel rdtsc cpu-cache

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

x86_64 - 为什么用 rdtsc/rdtscp 给程序计时会给出不合理的大数字?

我正在尝试使用 rdtscp 为子例程计时。这是我的程序:

; Setting up time
rdtscp                      ; Getting time
push rax                    ; Saving timestamp

; for(r9=0; r9<LOOP_SIZE; r9++)
mov r9, 0
lup0:
call subr
inc r9
cmp r9, LOOP_SIZE
jnz lup0

; Calculating time taken
pop rbx                     ; Loading old time
rdtscp                      ; Getting time
sub rax, rbx                ; Calculating difference
Run Code Online (Sandbox Code Playgroud)

如果LOOP_SIZE足够小,我会得到一致和预期的结果。但是,当我让它足够大(大约 10^9)时,我会从 10^9 飙升到 10^20。

; Result with "LOOP_SIZE equ 100000000"
971597237
; Result with "LOOP_SIZE equ 1000000000"
18446744072281657066
Run Code Online (Sandbox Code Playgroud)

我用来显示数字的方法将它们显示为无符号,所以我想象显示的大数字实际上是一个负数并且发生了溢出。然而,971597237甚至还没有接近 64 位整数的限制,所以,假设问题是溢出,为什么会发生呢?

assembly x86-64 rdtsc

2
推荐指数
1
解决办法
84
查看次数