目的:加时间戳打印是为了方便快速对性能耗时进行测试
比如想要测试printf这个函数调用的耗时
bind_core(4);
for(int i=0;i<MAX_SAMPLES;i++){
timing_now(now_tsc0);
printf("11111111");
timing_now(now_tsc1);
GATHERING_NS(series0,now_tsc0,now_tsc1,NULL);
}
操作步骤:
- 隔核
- 绑核
- 加一个循环
- 在printf前加开始时间戳
- 在printf后加结束时间戳
- 结束时间戳后加:GATHERING_NS(series0,now_tsc0,now_tsc1,NULL);
bind_core
#include <sched.h>
void bind_core(int core_i){
cpu_set_t cpus;
CPU_ZERO(&cpus);
CPU_SET(core_i, &cpus);
if(sched_setaffinity(0,sizeof(cpus),&cpus) == -1){
ERROR("failed bind core %u",core_i);
} else {
INFO("success to core %u",core_i);
}
}
MAX_SAMPLES
#define MAX_SAMPLES 512
timing_now()
#define timing_now(val) do{ \
struct timespec abc; \
clock_gettime(CLOCK_REALTIME, &abc); \
(val) = (unsigned long)abc.tv_sec * 1000000000lu + (unsigned long)abc.tv_nsec; \
} while(0)
now_tsc0、now_tsc1
typedef uint64_t timing_t;
static timing_t now_tsc0 , now_tsc1;
GATHERING_NS()
#define CYCLE_SAMPLES_MASK (MAX_SAMPLES - 1)
#define TXT(T) #T
#define GATHERING_NS(SERIES, SEQ, TSC, LEN)\
do { \
SERIES.samples[SERIES.count].seq = (SEQ); \
SERIES.samples[SERIES.count].tsc = (TSC); \
SERIES.samples[SERIES.count].len = (LEN); \
SERIES.count++; \
if( SERIES.count > CYCLE_SAMPLES_MASK ) { \
perf_latency_dump_ns(TXT(SERIES), SERIES.samples, MAX_SAMPLES); \
} \
SERIES.count = SERIES.count & CYCLE_SAMPLES_MASK; \
} while(0)
SERIES
typedef struct tsc_sample_struct {
timing_t seq;
timing_t tsc;
int len;
} tsc_sample_struct_t;
typedef struct series_struct {
tsc_sample_struct_t samples[MAX_SAMPLES];
uint32_t count;
} series_struct_t;
static series_struct_t series0;
perf_latency_dump_ns()
void perf_latency_dump_ns(const char *tag,tsc_sample_struct_t *stats, int count) {
int i;
for (i=0; i<count; i++) {
printf("perl:%s:%p seq=%04lu, value[%03d]=%luns, len=%d, balance=%ld\n",
tag, stats, stats[i].seq, i, stats[i].tsc, stats[i].len, stats[i].tsc - stats[i].seq);
}
}