相关疑难解决方法(0)

如何在x86_64上准确地对准未对齐的访问速度

答案中,我已经声明未对齐访问的速度与对齐访问的速度几乎相同(在x86/x86_64上).我没有任何数字来支持这个陈述,所以我已经为它创建了一个基准.

你看到这个基准测试有什么缺陷吗?你可以改进它(我的意思是,增加GB /秒,所以它更好地反映了真相)?

#include <sys/time.h>
#include <stdio.h>

template <int N>
__attribute__((noinline))
void loop32(const char *v) {
    for (int i=0; i<N; i+=160) {
        __asm__ ("mov     (%0), %%eax" : : "r"(v) :"eax");
        __asm__ ("mov 0x04(%0), %%eax" : : "r"(v) :"eax");
        __asm__ ("mov 0x08(%0), %%eax" : : "r"(v) :"eax");
        __asm__ ("mov 0x0c(%0), %%eax" : : "r"(v) :"eax");
        __asm__ ("mov 0x10(%0), %%eax" : : "r"(v) :"eax");
        __asm__ ("mov 0x14(%0), %%eax" : : "r"(v) :"eax");
        __asm__ ("mov 0x18(%0), %%eax" : : "r"(v) :"eax"); …
Run Code Online (Sandbox Code Playgroud)

performance benchmarking x86 x86-64 inline-assembly

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

为什么 CPUID + RDTSC 不可靠?

我正在尝试在 x86-64 处理器上分析执行时间的代码。我指的是这篇英特尔白皮书,并且还浏览了其他 SO 线程,讨论了在此处此处使用 RDTSCP 与 CPUID+RDTSC 的主题。

在上面提到的白皮书中,使用 CPUID+RDTSC 的方法被称为不可靠,并且也使用统计数据进行了证明。

CPUID+RDTSC 不可靠的原因可能是什么?

此外,同一白皮书中的图 1(最小值行为图)和图 2(方差行为图)中的图具有“方波”模式。什么解释了这种模式?

x86 intel microbenchmark rdtsc cpuid

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

_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

有人可以帮我理解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
查看次数

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

确定 AVX-512 FMA 装置的数量

是否可以使用 C++ 在运行时确定 AVX-512 FMA 单元的数量?
我已经有代码来确定 CPU 是否支持 AVX-512,但我无法确定 FMA 单元的数量。

c++ avx512

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

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

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