相关疑难解决方法(0)

Linux替代Windows高分辨率性能计数器API

我正在寻找Windows高分辨率性能计数器API的替代品,特别是以下API函数:

谢谢.

linux performancecounter

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

rdtsc计时器在linux中是不准确的吗?

 __inline__ uint64_t rdtsc() {
    uint32_t low, high;
    __asm__ __volatile__ (
        "xorl %%eax,%%eax \n    cpuid"
        ::: "%rax", "%rbx", "%rcx", "%rdx" );
    __asm__ __volatile__ (
                          "rdtsc" : "=a" (low), "=d" (high));
    return (uint64_t)high << 32 | low;
}
Run Code Online (Sandbox Code Playgroud)

我在程序中使用了上面的rdtsc函数作为计时器:以下代码导致312-344个时钟周期:

 start = rdtsc();
 stop = rdtsc();

 elapsed_ticks = (unsigned)((stop-start));
 printf("\n%u ticks\n",elapsed_ticks);
Run Code Online (Sandbox Code Playgroud)

每次运行上面的代码我都会得到不同的值.这是为什么?

我在Visual C++中运行相同的代码,它在"intrin.h"中使用了rdtsc函数.我得到了18个时钟的恒定值.是的,每次运行都是恒定的!有人可以解释一下吗?谢谢!

c++ linux

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

如何将此汇编时间戳函数转换为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
查看次数

获取时间戳的最快方法

我正在实现一些数据结构,其中我需要在一段时间后使某些条目无效,因此对于每个条目,我需要维护其插入时间戳。当我得到一个条目时,我需要再次获取时间戳并计算从插入开始的经过时间(如果它太旧,我无法使用它)。

许多线程高度满足此数据结构,因此我必须以最有效的方式获取此时间戳(oninsertfind)。效率在这里非常重要。

如果重要的话,我正在使用 C++ 开发的 linux 机器上工作。检索时间戳的最有效方法是什么?

顺便说一句,在我正在做的一些旧项目中,我记得我看到了一些直接从 CPU 获取时间戳的汇编命令(不记得命令了)。

c++ linux time cpu-registers

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

“ 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
查看次数

恒定非不变 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
查看次数

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
查看次数

使用 RDTSC 指令测量 C 中的代码执行时间

我编写了一个简单的程序来使用 RDTSC 指令测量代码执行时间。但是我不知道我的结果是否正确以及我的代码是否有问题......我不知道如何验证它。

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

#define N (1024*4)

unsigned cycles_low, cycles_high, cycles_low1, cycles_high1;

static __inline__ unsigned long long rdtsc(void)
{
    __asm__ __volatile__ ("RDTSC\n\t"
            "mov %%edx, %0\n\t"
            "mov %%eax, %1\n\t": "=r" (cycles_high), "=r" (cycles_low)::
            "%rax", "rbx", "rcx", "rdx");
}

static __inline__ unsigned long long rdtsc1(void)
{
    __asm__ __volatile__ ("RDTSC\n\t"
            "mov %%edx, %0\n\t"
            "mov %%eax, %1\n\t": "=r" (cycles_high1), "=r" (cycles_low1)::
            "%rax", "rbx", "rcx", "rdx");
}

int main(int argc, char* argv[])
{
    uint64_t start, end;

    rdtsc();
    malloc(N); …
Run Code Online (Sandbox Code Playgroud)

c

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

为什么在运行时添加两个值会有如此高的可变性?

我编写了一个计时函数,记录了函数的运行时间,并计算了多次运行的均值和标准差。我惊讶地发现即使是看似简单的任务(例如加两个双打)也有很高的标准偏差。我分析了python中的数据(请参见图)。C ++输出是19.6171 ns +/- 21.9653ns (82799807 runs)使用以下命令编译的:

gcc version 8.3.0 (Debian 8.3.0-19)
/usr/bin/c++ -O3 -DNDEBUG -std=gnu++17
Run Code Online (Sandbox Code Playgroud)

整个测试是在我的个人计算机上完成的,该计算机不是空闲的而是运行DE,浏览器,IDE和其他进程。测试期间有可用的RAM。我的带有HT的双核CPU空闲率低于10%。
在这种情况下,是否会出现从20 ns的平均值到50 µs的峰值?

运行时间图
这是的内容std::vector<double> run_times。我没有看到任何图案。 运行时图

运行时间的直方图
注意log y轴(此bin中的样本数)。 运行时间直方图

定时

gcc version 8.3.0 (Debian 8.3.0-19)
/usr/bin/c++ -O3 -DNDEBUG -std=gnu++17
Run Code Online (Sandbox Code Playgroud)

计时文件

#include <cstdint>
#include <ostream>
#include <cmath>
#include <algorithm>
#include <vector>
#include <chrono>
#include <numeric>
#include <fstream>


struct TimingResults{
    // all time results are in nanoseconds
    double mean;
    double standard_deviation;
    uint64_t number_of_runs;
};


std::ostream& operator<<(std::ostream& os, const TimingResults& results);


template …
Run Code Online (Sandbox Code Playgroud)

c++ benchmarking timing

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