Skip to content

Latest commit

 

History

History
130 lines (111 loc) · 3.68 KB

File metadata and controls

130 lines (111 loc) · 3.68 KB

小技巧汇总

本文档收录学习过程中遇到的小技巧,以期借助此可提高代码效率!

环绕情况下比较大小或计算差值

此宏定义在~/include/linux/jiffies.h,表达了a代表的时间是否在b后边,它们
的值为u32, 50天左右溢出一次,此比较可屏蔽溢出回绕问题。
#define time_after(a,b)		\
	(typecheck(unsigned long, a) && \
	 typecheck(unsigned long, b) && \
	 ((long)((b) - (a)) < 0))


由此可推导出防止回绕的差值计算式如下
diff = (long)a - (long)b

高精度计数器

linux内核提供的jiff计数器,精度不高,一般内核态HZ值为1000, 用户态为100, 构 建于此的函数包括clock/times()等。

如果需要度量非常短的时间,或需要极高的时间精度,就需要使用特定于平台的资源; 绝大多数处理器都包含随时钟周期不断递增的计数寄存器,它是完成高分辨率计时任 务的 唯一 可靠途径。

linux提供的函数

time()提供秒级精度 gettimeofday()提供微妙级精度 clock_gettime()提供纳秒级精度

TSC

最有名的计数器寄存器是TSC(timestamp counter, 时间戳计数器),x86平台从Pentium 开始提供,可通过rdtsc指令读取;不过多核时代,其精度值大大降低,建议利用内核 提供的高精度函数代替,如clock_gettime()

  • 不能保证同一块主板上每个核的TSC是同步的
  • CPU的时钟频率可能变化,如笔记本电脑的节能功能
  • 乱序执行导致RDTSC测量周期数不准,这个问题从Pentium Pro时代就存在
#include<stdio.h> 
#include<stdlib.h>
#include<linux/types.h>

#define TIMES 100
#define SIZE 1024

__u64 rdtsc()
{
    __u32 lo,hi;

    __asm__ __volatile__ ("rdtsc":"=a"(lo),"=d"(hi));
    return (__u64)hi<<32|lo;
}

int myfunction()
{
    int i;
    char *p = NULL;
    for(i = 0;i<TIMES;i++)
    {
        p = (char*)malloc(SIZE*sizeof(char));
        if(p)
        {
            free(p);
        }
        else
        {
            printf("malloc failed when i = %d\n",i);
        }
    }
    return 0;
}
int test_rdtsc()
{
    __u64 begin;
    __u64 end;

    begin = rdtsc();
    myfunction();
    end = rdtsc();
    printf("myfunction cost %llu CPU cycles\n",end-begin);
    return 0;
}

int main()
{
    test_rdtsc();
    return 0;
}

定制网卡名字, udev rules

通过udev可以定制网卡的名字

  • 查看pci信息
    查看.rules规则用到的字段
      udevadm info -a -p /sys/class/net/ens2f2
    查看执行过程,及暴露的环境变量(但不执行)
      udevadm test -a ADD /sys/class/net/ens2f2
        
  • 修改文件, /etc/udev/rules.d/99-net-interfaces.rules
    匹配MAC "00:22:46:3b:e0:67", 命名为"eth4"
      SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:22:46:3b:e0:67", NAME="eth4"
        

    :

    匹配PCI "", 命名为"eth4"
      SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", SUBSYSTEMS=="pci", KERNELS=="0000:02:00.2", NAME="eth4"
        
  • 验证是否生效
    方法1
      service network stop
      udevadm control --reload-rules
      udevadm trigger --attr-match=subsystem=net
      service network start
    方法2
      dpdk-devbind.py -u 0000:02:00.2
      udevadm control --reload-rules
      udevadm trigger --attr-match=subsystem=net
      dpdk-devbind.py -b igb  0000:02:00.2
        

python字典对象输出

  • 紧凑输出
    json.dumps([1, 2, 3, {'4': 5, '6': 7}], separators=(',', ':'))
        
  • 美化输出
    json.dumps({'4': 5, '6': 7}, sort_keys=True, indent=4)
        

构造分片报文/generate fragment packet

  • ICMP
    ping -s 2000 www.baidu.com     #通过-s指定报文长度, 需大于MTU
        
  • UDP
    参考 scapy_fragment.py