如何在Linux上查找此抖动的来源?
发布时间:2020-12-31 21:44:51 所属栏目:Linux 来源:网络整理
导读:我正在尝试解决 linux上的以下抖动问题.我用完全相同的方式调用sendto()200万次完全相同的数据.我的最小值/最大值/平均值是:最小值,最大值,平均值,1175,14211,1322.858685.那是纳秒.最小值是1175,平均值是1323,但最大值是14211,是平均值的10倍.我甚至不包括
文件tmp_1.txt清楚地显示了这样的事情: a.out-3346 [005] 33832.957658: softirq_raise: vec=1 [action=TIMER] a.out-3346 [005] 33832.957658: rcu_utilization: Start scheduler-tick a.out-3346 [005] 33832.957658: softirq_raise: vec=9 [action=RCU] a.out-3346 [005] 33832.957659: rcu_utilization: End scheduler-tick a.out-3346 [005] 33832.957660: sched_stat_runtime: comm=a.out pid=3346 runtime=2950209 [ns] vruntime=38264172961 [ns] a.out-3346 [005] 33832.957662: hrtimer_expire_exit: hrtimer=0xffff88087fd4eca0 a.out-3346 [005] 33832.957663: hrtimer_start: hrtimer=0xffff88087fd4eca0 function=tick_sched_timer expires=33819608000000 softexpires=33819608000000 a.out-3346 [005] 33832.957663: local_timer_exit: vector=239 a.out-3346 [005] 33832.957664: softirq_entry: vec=1 [action=TIMER] a.out-3346 [005] 33832.957666: softirq_exit: vec=1 [action=TIMER] a.out-3346 [005] 33832.957666: softirq_entry: vec=9 [action=RCU] a.out-3346 [005] 33832.957666: rcu_utilization: Start RCU core a.out-3346 [005] 33832.957667: rcu_utilization: End RCU core a.out-3346 [005] 33832.957667: softirq_exit: vec=9 [action=RCU] a.out-3346 [005] 33832.957668: tick_stop: success=yes msg= 我假设是抖动的原因.我尝试打开并写入/ sys / kernel / debug / tracing / trace_marker,这确实显示在跟踪文件中,但它没有我希望的那么有用.您还可以在之前和之后读取/ proc / softirqs,看看是否存在抖动时是否存在问题. 我添加了代码来读取/ proc / softirqs,并确保每次有抖动时,计时器滴答计数增加了一个.相反的情况并非如此,有时计时器计数在/ proc / softirqs中上升,但没有抖动,所以显然它取决于内核在计时器关闭时决定做什么: HI:,685 TIMER:,33295 NET_TX:,12 NET_RX:,4030892 BLOCK:,0 BLOCK_IOPOLL:,0 TASKLET:,55873 SCHED:,0 HRTIMER:,5 RCU:,7946 slow,11148 HI:,33296 NET_TX:,7947 有时RCU计数会增加1但有时不会增加.计时器计数总是加1. 这是最新的代码: #include <stdio.h> #include <sys/time.h> #include <inttypes.h> #include <stdint.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <netinet/in.h> #include <strings.h> #include <arpa/inet.h> #include <time.h> #include <unistd.h> #include <sys/syscall.h> /* g++ -O2 jitter.cpp sudo trace-cmd record -s 1000 -b 10000 -e all -o trace_1.dat `taskset -c 5 ./a.out > dfa2.tmp` sudo trace-cmd report -i trace_1.dat > tmp_1.txt */ #pragma pack( push ) #pragma pack( 1 ) #define MAX_CPUS 6 #define TARGET_CPU 5 typedef struct { char chName[13]; char chCPU[11*MAX_CPUS]; char chNewLine[8]; } procSoftIRQLine1; typedef struct { char chName[13]; char chCPU[11*MAX_CPUS]; char chNewLine; } procSoftIRQLine2; typedef struct { procSoftIRQLine1 h; procSoftIRQLine2 b[30]; } procSoftIRQ; #pragma pack(pop) FILE *pFProcSoftirq = NULL; procSoftIRQ data; void read_proc_softirqs() { rewind( pFProcSoftirq ); size_t tR = fread( (char *)&data,1,sizeof( data ),pFProcSoftirq ); size_t nP = sizeof( data.h ); for ( int i = 0; i < sizeof( data.b ) / sizeof( data.b[0] ) && nP < tR; i++ ) { printf("%.13s,%.11sn",data.b[i].chName,data.b[i].chCPU+11*(TARGET_CPU) ); nP += sizeof( procSoftIRQLine2 ) + 1; } } void udp_send() { struct timespec tpe1,0); FILE *pF = NULL; pFProcSoftirq = fopen( "/proc/softirqs","r" ); // pF = fopen( "/sys/kernel/debug/tracing/trace_marker","w" ); bzero(&servaddr,sizeof(servaddr)); servaddr.sin_family = AF_INET; // servaddr.sin_addr.s_addr=inet_addr("127.0.0.1"); servaddr.sin_addr.s_addr=inet_addr("192.168.5.51"); servaddr.sin_port=htons(3000); int nIterations = 1000000; // int64_t *tTime = new int64_t[nIterations]; int k = 0; for( k = 0; k < nIterations; k++) { // fputs( "#dfa,startingn",pF ); read_proc_softirqs(); clock_gettime(CLOCK_REALTIME,&tpe1); for ( int j = 0; j < 600; j++ ) memcpy( sendline,64 ); /* int n = sendto(sockfd,sizeof(servaddr)); if ( n != 64 ) printf("failed to sendn"); */ clock_gettime(CLOCK_REALTIME,&tpe2); int64_t t2 = ( tpe2.tv_sec - tpe1.tv_sec ) *1000000000 + tpe2.tv_nsec - tpe1.tv_nsec; if ( k > 0 ) { if ( t2 > 10000 ) { printf("slow,t2 ); read_proc_softirqs(); // if ( t2 > 10000 ) // fputs( "#dfa,slown",pF ); // else // fputs( "#dfa,fastn",pF ); // tTime[k] = t2; } } } } int main() { udp_send(); return 0; } 您必须将TARGET_CPU的值硬编码为要运行程序的CPU. TARGET_CPU应该是您将在taskset中使用的值-c TARGET_CPU ./a.out> out.txt. (编辑:晋中站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |