相关疑难解决方法(0)

RDTSC开销的差异

我正在构建一个微基准来测量性能变化,因为我在一些原始图像处理操作中尝试使用SIMD指令内在函数.但是,编写有用的微基准测试很困难,因此我想首先了解(如果可能的话)消除尽可能多的变异和误差源.

我必须考虑的一个因素是测量代码本身的开销.我正在使用RDTSC进行测量,我正在使用以下代码来查找测量开销:

extern inline unsigned long long __attribute__((always_inline)) rdtsc64() {
    unsigned int hi, lo;
        __asm__ __volatile__(
            "xorl %%eax, %%eax\n\t"
            "cpuid\n\t"
            "rdtsc"
        : "=a"(lo), "=d"(hi)
        : /* no inputs */
        : "rbx", "rcx");
    return ((unsigned long long)hi << 32ull) | (unsigned long long)lo;
}

unsigned int find_rdtsc_overhead() {
    const int trials = 1000000;

    std::vector<unsigned long long> times;
    times.resize(trials, 0.0);

    for (int i = 0; i < trials; ++i) {
        unsigned long long t_begin = rdtsc64();
        unsigned long long t_end = rdtsc64(); …
Run Code Online (Sandbox Code Playgroud)

c++ performance assembly intel rdtsc

13
推荐指数
1
解决办法
4342
查看次数

x86-64使用LFENCE

我正在尝试了解使用RDTSC/RDTSCP测量时间时使用栅栏的正确方法.关于与此相关的SO的几个问题已经得到了精心解答.我经历了其中一些.我也经历过关于同一主题的非常有用的文章:http: //www.intel.com/content/dam/www/public/us/en/documents/white-papers/ia-32-ia-64-基准-代码执行-paper.pdf

但是,在另一个在线博客中,有一个在x86上使用LFENCE而不是CPUID的例子.我想知道LFENCE如何阻止早期商店污染RDTSC测量.例如

<Instr A>
LFENCE/CPUID
RDTSC
<Code to be benchmarked>
LFENCE/CPUID
RDTSC 
Run Code Online (Sandbox Code Playgroud)

在上面的例子中,LFENCE确保它之前完成的所有早期加载(因为SDM说:LFENCE指令不能通过先前的读取.).但是早期的商店呢(比如,Instr A是商店)?我理解为什么CPUID有效,因为它是一个序列化指令,但LFENCE不是.

我发现的一个解释是在英特尔SDM VOL 3A第8.3节中,以下脚注:

LFENCE确实为指令排序提供了一些保证.它在本地完成所有先前指令之前不会执行,并且在LFENCE完成之前不会再执行指令.

所以LFENCE本质上就像一个MFENCE.在那种情况下,为什么我们需要两个单独的指令LFENCE和MFENCE?

我可能错过了一些东西.

提前致谢.

assembly x86-64 cpu-architecture atomicity

6
推荐指数
1
解决办法
1506
查看次数

加载和存储是否只有重新排序的指令?

我已经阅读了很多关于内存排序的文章,并且所有这些文章都只说CPU重新加载和存储.

CPU(我对x86 CPU特别感兴趣)是否仅重新排序加载和存储,并且不重新排序它具有的其余指令?

x86 cpu-architecture memory-barriers

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

clflush通过C函数使缓存行无效

我试图用来clflush手动驱逐缓存行,以确定缓存和行大小.我没有找到任何关于如何使用该指令的指南.我所看到的,是一些使用更高级别功能的代码.

有一个内核函数void clflush_cache_range(void *vaddr, unsigned int size),但我仍然不知道在我的代码中包含什么以及如何使用它.我不知道size该功能是什么.

更重要的是,我怎样才能确定该行被驱逐以验证我的代码的正确性?

更新:

这是我想要做的初始代码.

#include <immintrin.h>
#include <stdint.h>
#include <x86intrin.h>
#include <stdio.h>
int main()
{
  int array[ 100 ];
  /* will bring array in the cache */
  for ( int i = 0; i < 100; i++ )
    array[ i ] = i;

  /* FLUSH A LINE */
  /* each element is 4 bytes */
  /* assuming that cache line size is 64 bytes */
  /* array[0] till …
Run Code Online (Sandbox Code Playgroud)

c performance x86 intrinsics cpu-cache

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

使用rdtsc计算系统时间

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

c++ time assembly rdtsc

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