DPROBES (DTRACE_PROBE) 用于测量 1 微秒以下的高延迟内容

DPROBES (DTRACE_PROBE) 用于测量 1 微秒以下的高延迟内容

目前,我正在分析高延迟应用程序的性能,但我对自己的测量结果完全没有信心。到目前为止,我已经用于DPROBES仪器和密件抄送/功能用于测量。有人能够验证这些数字吗?另外,如果有人知道更好的方法,请告诉我。

测量usleep(1):平均值 = 53962 纳秒

#include <unistd.h>
#include <sys/sdt.h>

int main() {
   int i;
   for(i=0; i<1000000; i++){ 
   DTRACE_PROBE("hello-usdt", probe-main-start);
   usleep(1);
   DTRACE_PROBE("hello-usdt", probe-main-end);
   }
}

测量开销:avg = 788 纳秒

#include <sys/sdt.h>

int main() {
   int i;
   for(i=0; i<1000000; i++){ 
   DTRACE_PROBE("hello-usdt", probe-main-start);
   DTRACE_PROBE("hello-usdt", probe-main-end);
   }
}

作为开销,我可以从所有测量中减去 788 纳秒吗?

另一个例子nanosleep(200):avg = 52563 纳秒

#include <sys/sdt.h>
#include <unistd.h>
#include <time.h>
#include <stdio.h>
int main() {
  
    struct timespec tim, tim2;
    tim.tv_sec = 0;
    tim.tv_nsec = 200L;
    int i;
    for (i=0; i<100000; i++){
    DTRACE_PROBE("hello-usdt", probe-main-start);
    if(nanosleep(&tim , &tim2) < 0 ){
            printf("Nano sleep system call failed \n");
            return -1;
    }   
    DTRACE_PROBE("hello-usdt", probe-main-end);
    }
    printf("Nano sleep successfull \n");

    return 0;
}

对代码做了一点修改funclatency

# attach probes

usdt = USDT(path = "path to application")
usdt.enable_probe(probe = "probe-main-start", fn_name = "trace_func_entry")
usdt.enable_probe(probe = "probe-main-end", fn_name = "trace_func_return")
b = BPF(text = bpf_text, usdt_contexts = [usdt])

我是否无法使用此方法测量低于 0.8 微秒的任何数据?此外,我无法相信nanosleep(200)“睡过头”了 50 微秒。

答案1

测量 usleep(1):平均值 = 53962 纳秒

请理解,您的代码的顺序如下:

   DTRACE_PROBE("hello-usdt", probe-main-start);
   usleep(1);
   DTRACE_PROBE("hello-usdt", probe-main-end);

相关进程很可能在请求睡眠后被调度出去。
因此,仅当关联的进程重新调度时,才会执行以下 DTRACE_PROBE。因此,您的测量并不能可靠地测量所花费的时钟时间usleep(1),而是测量 1 µs 睡眠时间 + 根据系统活动而定的可变时间量,后者在任何情况下都远远优于 1 µs。
让我们冒险……50 倍以上……平均约为 50μs ;-)
在非实时环境中,我怀疑标准偏差在这一指标上相当高。


测量开销:avg = 788 纳秒。
作为开销,我可以从所有测量中减去 788 纳秒吗?

我们承认您的方法确实会测量 DTRACE_PROBE 引起的开销。
无论如何,就像在任何测量操作中一样,请首先考虑标准差。因为标准差越高,平均值的意义就越小。
如果对标准差感到满意,那么是的,请从测量值中减去平均值。
但是……好吧……我们所说的时间是 < 1 µs 吗?


另一个例子 nanosleep(200) :avg = 52563 纳秒

什么 ?再说一次……大约 50 µs 的漂移?多么奇怪 ?
请参阅我的答案的第一部分,该部分nanosleep也适用。如果还不够,请参阅nanosleep手动的:

此外,睡眠完成后,CPU 再次空闲执行调用线程之前可能仍然存在延迟。


我是否无法使用此方法测量低于 0.8 微秒的任何数据?此外,我无法相信 nanosleep(200) “睡过头”了 50 usec。

读完上面写的所有内容后,我希望您已经找到了最后一个问题的答案,该问题顺便也给出了前一个问题的答案:

不 !使用此方法您并非无法测量低于 800 ns 的任何东西。
但是,由于您的系统活动和硬件性能,您只能(我的意思是我也)无法测量任何阻塞调用所花费的时钟时间(无论什么调用都会立即触发调度程序调度进程),精度高于约 50 µs。

相关内容