memcpy性能测试用例设计

memcpy性能测试用例设计

    • 朴素思维
      • 获取系统当前时间
      • 执行多少次合适
    • 测试数据
      • 需要关注的点
      • 测试数据

背景:实现高性能memcpy函数。所以得先想清楚怎么测试性能!在网上也发现了一些测试用例,但是觉得不是很合理,在这里整理下思路,仅作笔记!

朴素思维

  1. 在执行memcpy前,获取系统当前时间start_time;
  2. 在执行memcpy后,获取系统当前时间end_time;
  3. end_time - start_time,即可得耗费时间

获取系统当前时间

有以下几种获取时间的方式

// 以下三个函数,均声明在  
time_t time(time_t * timer) ;		//s 秒级精度
int gettimeofday(struct timeval *tv, struct timezone *tz);	//us 微妙级精度
int clock_gettime(clockid_t clk_id, struct timespect *tp);	//ns 纳秒级精度

经过测试,执行一个printf 函数,需要400us左右,即0.4ms 毫秒。
个人觉得有些不可思议,一个小printf竟然需要耗费这么久时间!!
可能是函数消耗比较大,以后有空用汇编测试下

为方便以后扩展(可以轻易转化为us/ms/s),所以选取ns级精度时间函数 clock_gettime.
下为实例代码 参考链接

#include 
#include 
#include 

int main()
{
        struct timespec time_start={0, 0},time_end={0, 0}; 
        clock_gettime(CLOCK_REALTIME, &time_start);
        printf("start time : %llus,%llu ns \n", time_start.tv_sec, time_start.tv_nsec);
        clock_gettime(CLOCK_REALTIME, &time_end);
        printf("end time : %llus,%llu ns \n", time_end.tv_sec, time_end.tv_nsec);
        printf("duration time : %llus,%llu ns \n", time_end.tv_sec - time_start.tv_sec, time_end.tv_nsec - time_start.tv_nsec);

        return 1;
}

执行多少次合适

经过上面的测试,预估调用一次memcpy的耗时是ms us级别的。
memcpy的耗时和所要拷贝的数据规模有很大关系!

所以可能有这样几种情况:

  1. 数据规模较小:1B <= sizeof(src) <1KB
    此时,耗时很短,ms级别。由于系统负载问题,可能会波动的比较厉害,所以需要执行多次,取得平均每次memcpy的平均值;
char src[100] = "1";
char dst[100];
int n = 1000;
while (n--) {
	memcpy_self(dst, src, 100);
}
  1. 1KB <= sizeof(src) <1MB
    根据实际情况,采取1 / 3两种方案;
  2. 数据规模较大:1MB < sizeof(src) <1GB
    此时,耗时估计在s级别,受系统负载影响较小,获取执行一次的时间即可;
#define KB 1024
#define MB (1024*KB)
#define GB (1024*MB)
char src[GB] = "1";
char dst[GB] ;
memcpy_self(dst, src, GB);

测试数据

需要关注的点

经过一天的研究,发现有以下情况可能会影响到函数性能 (IA32架构)

  1. 数据对齐
    一般定义的int/char类型数据,都是对齐的。所以可能需要构造特殊结构体来实现未对齐的状况;
  2. 4K页
    如果大于4K页,可以考虑整页整页的拷贝(似乎利用了copy-on-write特性)

测试数据

鉴于系统负载的变换对memcpy性能评判的影响,所以需要让该函数执行一段时间(秒级别),求取单次拷贝的平均值,以此尽量降低负载变化对测量结果的影响。
如何让memcpy的执行时间达到一定规模:
对于拷贝内存较少的情况,循环拷贝。为了方便,这里暂定拷贝总内存为1GB。单词拷贝内存越小,执行的次数越多,总时间越长。 (经测试,1GB的消耗时间大约为秒级别)

  1. 单次拷贝1B,
  2. 单次拷贝8B,
  3. 单次拷贝9B,
  4. 单次拷贝64B
内存大小 glibc时长 我的时长
1B
8B
9B
64B
结构体
4KB
4MB
1GB

你可能感兴趣的:(libc,test)