加入收藏 | 设为首页 | 会员中心 | 我要投稿 衡阳站长网 (https://www.0734zz.cn/)- 数据集成、设备管理、备份、数据加密、智能搜索!
当前位置: 首页 > 服务器 > 搭建环境 > Linux > 正文

如何在Linux上查找此抖动的来源?

发布时间:2021-01-01 00:22:02 所属栏目: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.

(编辑:衡阳站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读