📄 cachebench.c
字号:
REGISTER DATATYPE wval = (DATATYPE)0xf;
flushall(1);
assert(signal(SIGALRM,handler) != SIG_ERR);
wval = (DATATYPE)limit;
alarm(duration);
TIMER_START;
while (keepgoing)
{
for (index = 0; index < limit; index++)
x[index] = wval;
loops++;
}
TIMER_STOP;
fake_out_optimizations(x,limit*sizeof(DATATYPE));
*oloops = loops;
*ous = TIMER_ELAPSED_US;
{
double refcnt = ((double)loops*(double)limit)+(double)index;
DBG(fprintf(stderr,"T: %d loops at limit %d took %f us, %f refs.\n",loops,limit,*ous,refcnt));
return(refcnt);
}
}
double hand_benchmark_cache_wonly(REGISTER DATATYPE *x, REGISTER int limit, int *oloops, double *ous)
{
REGISTER int index = 0, loops = 0;
REGISTER DATATYPE wval = (DATATYPE)0xf;
flushall(1);
keepgoing = 1;
assert(signal(SIGALRM,handler) != SIG_ERR);
limit -= 8; wval = (DATATYPE)limit;
alarm(duration);
TIMER_START;
again:
x[index] = wval;
x[index+1] = wval;
x[index+2] = wval;
x[index+3] = wval;
x[index+4] = wval;
x[index+5] = wval;
x[index+6] = wval;
x[index+7] = wval;
if ((index+=8) < limit)
goto again;
else if (keepgoing)
{
index = 0;
loops++;
goto again;
}
TIMER_STOP;
index += 8;
fake_out_optimizations(x,limit*sizeof(DATATYPE));
*oloops = loops;
*ous = TIMER_ELAPSED_US;
{
double refcnt = ((double)loops*(double)limit)+(double)index;
DBG(fprintf(stderr,"T: %d loops at limit %d took %f us, %f refs.\n",loops,limit,*ous,refcnt));
return(refcnt);
}
}
double benchmark_cache(REGISTER DATATYPE *x, REGISTER int limit, int *oloops, double *ous)
{
REGISTER int index = 0, loops = 0;
flushall(1);
assert(signal(SIGALRM,handler) != SIG_ERR);
alarm(duration);
TIMER_START;
while (keepgoing)
{
for (index = 0; index < limit; index++)
x[index]++;
loops++;
}
TIMER_STOP;
fake_out_optimizations(x,limit*sizeof(DATATYPE));
*oloops = loops;
*ous = TIMER_ELAPSED_US;
{
double refcnt = ((double)loops*(double)limit)+(double)index;
DBG(fprintf(stderr,"T: %d loops at limit %d took %f us, %f refs.\n",loops,limit,*ous,refcnt));
return(refcnt);
}
}
double hand_benchmark_cache(REGISTER DATATYPE *x, REGISTER int limit, int *oloops, double *ous)
{
REGISTER int index = 0, loops = 0;
flushall(1);
keepgoing = 1;
assert(signal(SIGALRM,handler) != SIG_ERR);
alarm(duration);
TIMER_START;
again:
x[index]++;
x[index+1]++;
x[index+2]++;
x[index+3]++;
x[index+4]++;
x[index+5]++;
x[index+6]++;
x[index+7]++;
if ((index+=8) <= limit-8)
goto again;
else if (keepgoing)
{
index = 0;
loops++;
goto again;
}
TIMER_STOP;
fake_out_optimizations(x,limit*sizeof(DATATYPE));
*oloops = loops;
*ous = TIMER_ELAPSED_US;
{
double refcnt = ((double)loops*(double)limit)+(double)index;
DBG(fprintf(stderr,"T: %d loops at limit %d took %f us, %f refs.\n",loops,limit,*ous,refcnt));
return(refcnt);
}
}
double benchmark_cache_memory_copy(REGISTER void *x, REGISTER void *y, REGISTER int bytes, int *oloops, double *ous)
{
REGISTER int loops = 0;
flushall(1);
assert(signal(SIGALRM,handler) != SIG_ERR);
alarm(duration);
TIMER_START;
while (keepgoing)
{
memcpy(x,y,bytes);
loops++;
}
TIMER_STOP;
fake_out_optimizations(x,bytes);
fake_out_optimizations(y,bytes);
*ous = TIMER_ELAPSED_US;
*oloops = loops;
return((double)loops*(double)bytes);
}
double benchmark_cache_memory_set(REGISTER void *x, REGISTER int bytes, int *oloops, double *ous)
{
REGISTER int loops = 0;
flushall(1);
assert(signal(SIGALRM,handler) != SIG_ERR);
alarm(duration);
TIMER_START;
while (keepgoing)
{
memset(x,0xf0,bytes);
loops++;
}
TIMER_STOP;
fake_out_optimizations(x,bytes);
*ous = TIMER_ELAPSED_US;
*oloops = loops;
return((double)loops*(double)bytes);
}
void initialize_sizes(int *sizes)
{
int i,j;
for (j=0; j<timeslots; j+=resolution)
{
sizes[j] = 1<<(CACHE_MIN_BITS+j/resolution);
DBG(printf("POW: %d %d\n",j,sizes[j]));
for (i=1;i<resolution;i++)
{
if (j+i < timeslots)
{
sizes[j+i] = sizes[j] + i*(sizes[j]/resolution);
sizes[j+i] = sizes[j+i] - sizes[j+i]%(int)sizeof(DATATYPE);
DBG(printf("SUB: %d %d\n",j+i,sizes[j+i]));
}
}
}
}
void do_memory_copy(int *sizes, void *x, double *times, double *bws, double *percents)
{
int limit, j, i, tloops;
double refcnt, overhead_per_ref = 0.0, tmicrosec;
/* double nullcnt = 0.0, cmicrosec = 0.0; */
void *y;
assert(y = (void *)malloc(memsize));
memset(y,0x0f,memsize);
if (isatty(1))
{
printf("\n\t\t%sMemory Copy Library Cache Test\n\n",
(!(type & NOCALIBRATE)) ? "Calibrated " : "");
printf("C Size\t\tNanosec\t\tMB/sec\t\t%% Chnge\n");
printf("-------\t\t-------\t\t-------\t\t-------\n");
}
for (i = 0; i < timeslots; i++)
{
limit = sizes[i];
for (j = 0; j < repeat_count; j++)
{
refcnt = benchmark_cache_memory_copy(x, y, limit, &tloops, &tmicrosec) * 2.0;
/* if (type & NOCALIBRATE)
{
nullcnt = 0.0;
overhead_per_ref = 0.0;
cmicrosec = 0.0;
}
else
{
nullcnt = calibrate_benchmark_cache_memory_copy(x, tloops, limit, &cmicrosec);
overhead_per_ref = (cmicrosec*1000.0) / nullcnt;
DBG(fprintf(stderr,"C: %f ns per ref.\n",overhead_per_ref));
} */
compute_stats(i,j,refcnt,overhead_per_ref,times,bws,percents,sizes,tmicrosec,1);
}
}
/* if ((isatty(1))&&(type&GUESSCACHESIZE))
compute_cache_sizes(times,bws,percents,sizes); */
free(y);
}
void do_memory_set(int *sizes, DATATYPE *x, double *times, double *bws, double *percents)
{
int limit, j, i, tloops;
double refcnt, overhead_per_ref = 0.0, tmicrosec;
/* double nullcnt = 0.0, cmicrosec = 0.0; */
if (isatty(1))
{
printf("\n\t\t%sMemory Set Library Cache Test\n\n",
((!(type & NOCALIBRATE)) ? "Calibrated " : ""));
printf("C Size\t\tNanosec\t\tMB/sec\t\t%% Chnge\n");
printf("-------\t\t-------\t\t-------\t\t-------\n");
}
for (i = 0; i < timeslots; i++)
{
limit = sizes[i];
for (j = 0; j < repeat_count; j++)
{
refcnt = benchmark_cache_memory_set(x, limit, &tloops, &tmicrosec);
/* if (type & NOCALIBRATE)
{
nullcnt = 0.0;
overhead_per_ref = 0.0;
cmicrosec = 0.0;
}
else
{
nullcnt = calibrate_benchmark_cache_memory_copy(x, tloops, limit, &cmicrosec);
overhead_per_ref = (cmicrosec*1000.0) / nullcnt;
DBG(fprintf(stderr,"C: %f ns per ref.\n",overhead_per_ref));
} */
compute_stats(i,j,refcnt,overhead_per_ref,times,bws,percents,sizes,tmicrosec,1);
}
}
/* if ((isatty(1))&&(type&GUESSCACHESIZE))
compute_cache_sizes(times,bws,percents,sizes); */
}
void do_read_only(int *sizes, DATATYPE *x, double *times, double *bws, double *percents)
{
int limit, j, i, tloops;
double refcnt, overhead_per_ref = 0.0, tmicrosec;
/* double nullcnt = 0.0, cmicrosec = 0.0; */
if (isatty(1))
{
printf("\n\t\t%s%s%s Read Cache Test\n\n",
((type & HANDTUNED) ? "Tuned " : ""),
((!(type & NOCALIBRATE)) ? "Calibrated " : ""), DATASTRING);
printf("C Size\t\tNanosec\t\tMB/sec\t\t%% Chnge\n");
printf("-------\t\t-------\t\t-------\t\t-------\n");
}
for (i = 0; i < timeslots; i++)
{
limit = sizes[i] / (int)sizeof(DATATYPE);
for (j = 0; j < repeat_count; j++)
{
if (type & HANDTUNED)
refcnt = hand_benchmark_cache_ronly(x, limit, &tloops, &tmicrosec);
else
refcnt = benchmark_cache_ronly(x, limit, &tloops, &tmicrosec);
/* if (type & NOCALIBRATE)
{
nullcnt = 0.0;
overhead_per_ref = 0.0;
cmicrosec = 0.0;
}
else
{
nullcnt = calibrate_benchmark(x, tloops, limit, &cmicrosec);
overhead_per_ref = (cmicrosec*1000.0) / nullcnt;
DBG(fprintf(stderr,"C: %f ns per ref.\n",overhead_per_ref));
} */
compute_stats(i,j,refcnt,overhead_per_ref,times,bws,percents,sizes,tmicrosec,sizeof(DATATYPE));
}
}
/* if ((isatty(1))&&(type&GUESSCACHESIZE))
compute_cache_sizes(times,bws,percents,sizes); */
}
void do_write_only(int *sizes, DATATYPE *x, double *times, double *bws, double *percents)
{
int limit, j, i, tloops;
double refcnt, overhead_per_ref = 0.0, tmicrosec;
/* double nullcnt = 0.0, cmicrosec = 0.0; */
if (isatty(1))
{
printf("\n\t\t%s%s%s Write Cache Test\n\n",
((type & HANDTUNED) ? "Tuned " : ""),
((!(type & NOCALIBRATE)) ? "Calibrated " : ""), DATASTRING);
printf("C Size\t\tNanosec\t\tMB/sec\t\t%% Chnge\n");
printf("-------\t\t-------\t\t-------\t\t-------\n");
}
for (i = 0; i < timeslots; i++)
{
limit = sizes[i] / (int)sizeof(DATATYPE);
for (j = 0; j < repeat_count; j++)
{
if (type & HANDTUNED)
refcnt = hand_benchmark_cache_wonly(x, limit, &tloops, &tmicrosec);
else
refcnt = benchmark_cache_wonly(x, limit, &tloops, &tmicrosec);
/* if (type & NOCALIBRATE)
{
nullcnt = 0.0;
overhead_per_ref = 0.0;
cmicrosec = 0.0;
}
else
{
nullcnt = calibrate_benchmark(x, tloops, limit, &cmicrosec);
overhead_per_ref = (cmicrosec*1000.0) / nullcnt;
DBG(fprintf(stderr,"C: %f ns per ref.\n",overhead_per_ref));
} */
compute_stats(i,j,refcnt,overhead_per_ref,times,bws,percents,sizes,tmicrosec,sizeof(DATATYPE));
}
}
/* if ((isatty(1))&&(type&GUESSCACHESIZE))
compute_cache_sizes(times,bws,percents,sizes); */
}
void do_read_write(int *sizes, DATATYPE *x, double *times, double *bws, double *percents)
{
int limit, j, i, tloops;
double refcnt, overhead_per_ref = 0.0, tmicrosec;
/* double nullcnt = 0.0, cmicrosec = 0.0; */
if (isatty(1))
{
printf("\n\t\t%s%s%s RMW Cache Test\n\n",
((type & HANDTUNED) ? "Tuned " : ""),
((!(type & NOCALIBRATE)) ? "Calibrated " : ""), DATASTRING);
printf("C Size\t\tNanosec\t\tMB/sec\t\t%% Chnge\n");
printf("-------\t\t-------\t\t-------\t\t-------\n");
}
for (i = 0; i < timeslots; i++)
{
limit = sizes[i] / (int)sizeof(DATATYPE);
for (j = 0; j < repeat_count; j++)
{
if (type & HANDTUNED)
refcnt = hand_benchmark_cache(x, limit, &tloops, &tmicrosec) * 2.0;
else
refcnt = benchmark_cache(x, limit, &tloops, &tmicrosec) * 2.0;
/* if (type & NOCALIBRATE)
{
nullcnt = 0.0;
overhead_per_ref = 0.0;
cmicrosec = 0.0;
}
else
{
nullcnt = calibrate_benchmark(x, tloops, limit, &cmicrosec);
nullcnt *= 2;
overhead_per_ref = (cmicrosec*1000.0) / nullcnt;
DBG(fprintf(stderr,"C: %f ns per ref.\n",overhead_per_ref));
} */
compute_stats(i,j,refcnt,overhead_per_ref,times,bws,percents,sizes,tmicrosec,sizeof(DATATYPE));
}
}
/* if ((isatty(1))&&(type&GUESSCACHESIZE))
compute_cache_sizes(times,bws,percents,sizes); */
}
int ksCacheTest(int argc, char **argv)
{
DATATYPE *x;
int *sizes;
double *times, *bws, *percents;
type = usage(argc, argv);
assert(sizes = (int *)malloc(timeslots*sizeof(int)));
memset(sizes,0x00,(timeslots*sizeof(int)));
assert(times = (double *)malloc(timeslots*repeat_count*sizeof(double)));
memset(times,0x00,(timeslots*repeat_count*sizeof(double)));
assert(bws = (double *)malloc(timeslots*repeat_count*sizeof(double)));
memset(bws,0x00,(timeslots*repeat_count*sizeof(double)));
assert(percents = (double *)malloc(timeslots*repeat_count*sizeof(double)));
memset(percents,0x00,(timeslots*repeat_count*sizeof(double)));
assert(x = (DATATYPE *)malloc(memsize));
memset((void *)x,0x00,memsize);
initialize_sizes(sizes);
#if 0
printf("--- Debug: mem [%p] DATATYPE-size[%d] memsize=[%ld]\n",
x, sizeof(DATATYPE), memsize);
#endif
/* Measure cache */
if (type & MEMORYSET)
{
do_memory_set(sizes,x,times,bws,percents);
}
if (type & MEMORYCOPY)
{
do_memory_copy(sizes,x,times,bws,percents);
}
if (type & READONLY)
{
do_read_only(sizes,x,times,bws,percents);
}
if (type & WRITEONLY)
{
do_write_only(sizes,x,times,bws,percents);
}
if (type & READWRITE)
{
do_read_write(sizes,x,times,bws,percents);
}
flushall(0);
exit(0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -