相关疑难解决方法(0)

clock_gettime()是否适合亚微秒时序?

在我们的应用程序的Linux版本中,我需要一个用于嵌入式探查器的高分辨率计时器.我们的分析器测量的范围与单个功能一样小,因此它需要一个优于25纳秒的定时器精度.

以前我们的实现使用内联汇编和rdtsc操作直接从CPU查询高频定时器,但这是有问题的,需要经常重新校准.

所以我尝试使用该clock_gettime函数来查询CLOCK_PROCESS_CPUTIME_ID.文档声称这给了我纳秒时间,但我发现单次调用的开销clock_gettime()超过250ns.这使得不可能将事件计时100ns,并且在计时器功能上具有如此高的开销会严重降低应用程序性能,从而扭曲配置文件超出值.(我们每秒有数十万个分析节点.)

有没有办法调用clock_gettime()开销小于¼μs?或者是否有其他方法可以可靠地获得时间戳计数器,开销<25ns?还是我坚持使用rdtsc

下面是我过去常用的代码clock_gettime().

// calls gettimeofday() to return wall-clock time in seconds:
extern double Get_FloatTime();
enum { TESTRUNS = 1024*1024*4 };

// time the high-frequency timer against the wall clock
{
    double fa = Get_FloatTime();
    timespec spec; 
    clock_getres( CLOCK_PROCESS_CPUTIME_ID, &spec );
    printf("CLOCK_PROCESS_CPUTIME_ID resolution: %ld sec %ld nano\n", 
            spec.tv_sec, spec.tv_nsec );
    for ( int i = 0 ; i < TESTRUNS ; ++ i …
Run Code Online (Sandbox Code Playgroud)

linux ubuntu performance profiling

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

使用背靠背rdtsc进行负时钟周期测量?

我正在编写一个C代码,用于测量获取信号量所需的时钟周期数.我正在使用rdtsc,在对信号量进行测量之前,我连续两次调用rdtsc来测量开销.我在for循环中重复了这么多次,然后我将平均值用作rdtsc开销.

这是正确的,首先要使用平均值吗?

尽管如此,这里的一个大问题是,有时我会得到开销的负值(不一定是平均值,但至少是for循环中的部分值).

这也影响了连续计算sem_wait()操作所需的cpu周期数,有时也证明是负数.如果我写的不清楚,这里有一部分我正在编写的代码.

为什么我会得到这样的负值?


(编者注:请参阅获取CPU周期计数?以获得完整的64位时间戳的正确和可移植方式."=A"编译为x86-64时,asm约束只能得到低或高32位,具体取决于寄存器分配是否发生为uint64_t输出选择RAX或RDX .它不会选择edx:eax.)

(编辑的第二个注释:哎呀,这就是为什么我们得到负面结果的答案.仍然值得留下一个注释作为警告,不要复制这个rdtsc实现.)


#include <semaphore.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <inttypes.h>

static inline uint64_t get_cycles()
{
  uint64_t t;
           // editor's note: "=A" is unsafe for this in x86-64
  __asm volatile ("rdtsc" : "=A"(t));
  return t;
}

int num_measures = 10;

int main ()
{
   int i, value, res1, res2;
   uint64_t c1, c2;
   int tsccost, tot, a;

   tot=0;    

   for(i=0; i<num_measures; i++)
   { …
Run Code Online (Sandbox Code Playgroud)

c x86-64 overhead inline-assembly rdtsc

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

现代CPU的每个刻度的缓存带宽

现代CPU的缓存访问速度是多少?Intel P4,Core2,Corei7,AMD每个处理器时钟周期内可以从内存中读取或写入多少字节?

请回答理论(ld/sd单位的宽度及其uOPs/tick的吞吐量)和实际数字(甚至是memcpy速度测试,或STREAM基准测试),如果有的话.

PS是问题,与汇编程序中的最大加载/存储指令率有关.可以有理论加载速率(所有每个Tick的指令都是最宽的负载),但是处理器只能给出部分这样的,一个实际的加载限制.

cpu performance caching cpu-architecture cpu-cache

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

系统上的缓存大小估算?

我从这个链接(https://gist.github.com/jiewmeng/3787223)获得了这个程序.我一直在网上搜索,以便更好地理解处理器缓存(L1和L2).我想成为能够编写一个程序,让我能够猜测我的新笔记本电脑上L1和L2缓存的大小.(仅用于学习目的.我知道我可以检查规格.)

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define KB 1024
#define MB 1024 * 1024

int main() {
    unsigned int steps = 256 * 1024 * 1024;
    static int arr[4 * 1024 * 1024];
    int lengthMod;
    unsigned int i;
    double timeTaken;
    clock_t start;
    int sizes[] = {
        1 * KB, 4 * KB, 8 * KB, 16 * KB, 32 * KB, 64 * KB, 128 * KB, 256 * KB,
        512 * KB, 1 * MB, 1.5 …
Run Code Online (Sandbox Code Playgroud)

c performance caching cpu-cache

10
推荐指数
1
解决办法
1813
查看次数

如何使用 C 测量 L1、L2 和 L3 缓存延迟?

我对此有一个总体的想法。这就是我的想法:

首先,找出我将使用的 L1 缓存的大小。然后创建一个数组(字节数足够大以适合 L1 缓存),编写一个程序来访问数组的每个元素。然后在每几个循环中创建时间戳。

对于 L2 缓存中的延迟,我可以增大阵列以到达 L2 缓存。

但实际上我不知道如何开始。我不清楚每个缓存的数组应该有多大,以及如何用上面的想法编写这个 C 程序。

谁能帮我写一下这个C程序吗?任何帮助将不胜感激!

多谢!

c arrays caching

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

内存层次结构延迟信息

这篇文章的"示例"部分中,作者列出了所有内存组件寄存器/ L1/L2/RAM的延迟...我的问题是:如何测量(在线查找)任何给定芯片的实际延迟?让我们说吧

model name  : Intel(R) Core(TM)2 Duo CPU     E4600  @ 2.40GHz
stepping    : 13
cpu MHz     : 1200.000
Run Code Online (Sandbox Code Playgroud)

我也尝试过从英特尔手册中获取信息,但对于我的生活,这些事情是巨大的,我不知道在哪里寻找信息.

谢谢.

memory latency

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

多态的成本

我在x86-64中查看下面的虚方法调用:

mov     rcx, qword ptr [x]   
mov     rax, qword ptr [rcx]
call    qword ptr [rax+8]
Run Code Online (Sandbox Code Playgroud)

以及Agner Fog的延迟表:

http://www.agner.org/optimize/instruction_tables.pdf

当我使用Ivy Bridge CPU时,我正在查看第175页.

  1. 我是否正确,前两个MOV指令都只占用2个(它们都是移动存储器来注册)CPU周期?我以为对虚拟方法的调用比这慢?

  2. 在178页的指令延迟表中,它表​​示此调用的延迟是2个CPU周期(我认为?).CALLCALL'r'(寄存器)和CALL'm'(存储器)相比,'near'意味着什么?

  3. 所以根据Fog小册子,上面的ASM确实需要6个CPU周期,我没有误解过任何东西?

编辑:我将虚函数调用更改为vtable中的第二个.

cpu x86 assembly branch-prediction

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

C++ Cache性能奇怪的行为

我读了一篇文章(1.5岁http://www.drdobbs.com/parallel/cache-friendly-code-solving-manycores-ne/240012736),其中讨论了缓存性能和数据大小.他们展示了以下代码,他们说这些代码是在i7(沙桥)上运行的

static volatile int array[Size];
static void test_function(void)
{
    for (int i = 0; i < Iterations; i++)
        for (int x = 0; x < Size; x++)
          array[x]++;
}
Run Code Online (Sandbox Code Playgroud)

他们声称如果他们保持Size*Iterations不变,增加Size,当数组内存中的大小增加超过L2缓存大小时,他们会观察到执行时间(10x)的巨大峰值.

作为我自己的练习,我想尝试一下,看看我是否可以为我的机器重现他们的结果.(i7 3770k,win7,visual c ++ 2012编译器,Win32调试模式,未启用优化).令我惊讶的是,我无法看到执行所花费的时间增加(甚至超过L3缓存大小),这让我觉得编译器在某种程度上优化了这段代码.但我也没有看到任何优化.我看到的唯一的速度变化是,在我的机器的字大小以下,它需要稍长.以下是我的时间,代码清单和相关的反汇编.

有谁知道原因:

1)为什么不管阵列的大小如何,所用的时间都不会增加?或者我怎么能找到?

2)为什么所花费的时间从高处开始然后减小直到达到缓存行大小,如果数据小于行大小,是否应该在没有从缓存读取的情况下处理更多迭代?


时序:

Size=1,Iterations=1073741824, Time=3829
Size=2,Iterations=536870912, Time=2625
Size=4,Iterations=268435456, Time=2563
Size=16,Iterations=67108864, Time=2906
Size=32,Iterations=33554432, Time=3469
Size=64,Iterations=16777216, Time=3250
Size=256,Iterations=4194304, Time=3140
Size=1024,Iterations=1048576, Time=3110
Size=2048,Iterations=524288, Time=3187
Size=4096,Iterations=262144, Time=3078
Size=8192,Iterations=131072, Time=3125
Size=16384,Iterations=65536, Time=3109
Size=32768,Iterations=32768, Time=3078
Size=65536,Iterations=16384, Time=3078
Size=262144,Iterations=4096, Time=3172
Size=524288,Iterations=2048, Time=3109
Size=1048576,Iterations=1024, Time=3094
Size=2097152,Iterations=512, Time=3313
Size=4194304,Iterations=256, Time=3391
Size=8388608,Iterations=128, …
Run Code Online (Sandbox Code Playgroud)

c++ performance caching

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

时钟周期内的缓存未命中延迟

为了测量程序中缓存未命中的影响,我想要计算缓存未命中对用于实际计算的周期造成的延迟。\n我用它来perf stat测量周期、L1 负载、L1 未命中、LLC 负载和 LLC - 我的程序中遗漏了。这是一个示例输出:

\n
               467\xe2\x80\xaf769,70 msec task-clock                #    1,000 CPUs utilized          \n        1\xe2\x80\xaf234\xe2\x80\xaf063\xe2\x80\xaf672\xe2\x80\xaf432      cycles                    #    2,638 GHz                      (62,50%)\n          572\xe2\x80\xaf761\xe2\x80\xaf379\xe2\x80\xaf098      instructions              #    0,46  insn per cycle           (75,00%)\n          129\xe2\x80\xaf143\xe2\x80\xaf035\xe2\x80\xaf219      branches                  #  276,083 M/sec                    (75,00%)\n            6\xe2\x80\xaf457\xe2\x80\xaf141\xe2\x80\xaf079      branch-misses             #    5,00% of all branches          (75,00%)\n          195\xe2\x80\xaf360\xe2\x80\xaf583\xe2\x80\xaf052      L1-dcache-loads           #  417,643 M/sec                    (75,00%)\n           33\xe2\x80\xaf224\xe2\x80\xaf066\xe2\x80\xaf301      L1-dcache-load-misses     #   17,01% of all L1-dcache hits    (75,00%)\n           20\xe2\x80\xaf620\xe2\x80\xaf655\xe2\x80\xaf322      LLC-loads                 #   44,083 M/sec                    (50,00%)\n            6\xe2\x80\xaf030\xe2\x80\xaf530\xe2\x80\xaf728      LLC-load-misses           #   29,25% of all LL-cache hits     (50,00%)\n
Run Code Online (Sandbox Code Playgroud)\n

那么我的问题是:\n如何将缓存未命中数转换为“丢失”时钟周期数? …

performance latency cpu-architecture cpu-cache perf

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