#ifdef __sun
#pragma ident "@(#)lmbench_bw_mem.c 1.0 20060814 Apple Inc."
#endif
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include "../libmicro.h"
#define TRIES 11 // value from bench.h in lmbench
#define TYPE int
static volatile u_int64_t use_result_dummy;
void use_int(int result) { use_result_dummy += result; }
void rd(iter_t iterations, void *cookie);
void wr(iter_t iterations, void *cookie);
void rdwr(iter_t iterations, void *cookie);
void mcp(iter_t iterations, void *cookie);
void fwr(iter_t iterations, void *cookie);
void frd(iter_t iterations, void *cookie);
void fcp(iter_t iterations, void *cookie);
void loop_bzero(iter_t iterations, void *cookie);
void loop_bcopy(iter_t iterations, void *cookie);
void init_overhead(iter_t iterations, void *cookie);
void init_loop(iter_t iterations, void *cookie);
void cleanup(iter_t iterations, void *cookie);
typedef struct _state {
double overhead;
size_t nbytes;
int need_buf2;
int aligned;
TYPE *buf;
TYPE *buf2;
TYPE *buf2_orig;
TYPE *lastone;
size_t N;
} state_t;
typedef struct {
double overhead;
size_t nbytes;
int need_buf2;
int aligned;
TYPE *buf;
TYPE *buf2;
TYPE *buf2_orig;
TYPE *lastone;
size_t N;
int parallel;
int warmup;
int repetitions;
} tsd_t;
static int optp = 1;
static int optw = 0;
static int optn = TRIES;
static int opt_size = 0;
static char *opt_what;
void
init_overhead(iter_t iterations, void *cookie)
{
}
void
init_loop(iter_t iterations, void *cookie)
{
tsd_t *ts = (tsd_t *)cookie;
if (iterations) return;
ts->buf = (TYPE *)valloc(ts->nbytes);
ts->buf2_orig = NULL;
ts->lastone = (TYPE*)ts->buf - 1;
ts->lastone = (TYPE*)((char *)ts->buf + ts->nbytes - 512);
ts->N = ts->nbytes;
if (!ts->buf) {
perror("malloc");
exit(1);
}
bzero((void*)ts->buf, ts->nbytes);
if (ts->need_buf2 == 1) {
ts->buf2_orig = ts->buf2 = (TYPE *)valloc(ts->nbytes + 2048);
if (!ts->buf2) {
perror("malloc");
exit(1);
}
if (ts->aligned) {
char *tmp = (char *)ts->buf2;
tmp += 2048 - 128;
ts->buf2 = (TYPE *)tmp;
}
}
}
void
cleanup(iter_t iterations, void *cookie)
{
tsd_t *ts = (tsd_t *)cookie;
if (iterations) return;
free(ts->buf);
if (ts->buf2_orig) free(ts->buf2_orig);
}
void
rd(iter_t iterations, void *cookie)
{
tsd_t *ts = (tsd_t *)cookie;
register TYPE *lastone = ts->lastone;
register int sum = 0;
while (iterations-- > 0) {
register TYPE *p = ts->buf;
while (p <= lastone) {
sum +=
#define DOIT(i) p[i]+
DOIT(0) DOIT(4) DOIT(8) DOIT(12) DOIT(16) DOIT(20) DOIT(24)
DOIT(28) DOIT(32) DOIT(36) DOIT(40) DOIT(44) DOIT(48) DOIT(52)
DOIT(56) DOIT(60) DOIT(64) DOIT(68) DOIT(72) DOIT(76)
DOIT(80) DOIT(84) DOIT(88) DOIT(92) DOIT(96) DOIT(100)
DOIT(104) DOIT(108) DOIT(112) DOIT(116) DOIT(120)
p[124];
p += 128;
}
}
use_int(sum);
}
#undef DOIT
void
wr(iter_t iterations, void *cookie)
{
tsd_t *ts = (tsd_t *)cookie;
register TYPE *lastone = ts->lastone;
while (iterations-- > 0) {
register TYPE *p = ts->buf;
while (p <= lastone) {
#define DOIT(i) p[i] = 1;
DOIT(0) DOIT(4) DOIT(8) DOIT(12) DOIT(16) DOIT(20) DOIT(24)
DOIT(28) DOIT(32) DOIT(36) DOIT(40) DOIT(44) DOIT(48) DOIT(52)
DOIT(56) DOIT(60) DOIT(64) DOIT(68) DOIT(72) DOIT(76)
DOIT(80) DOIT(84) DOIT(88) DOIT(92) DOIT(96) DOIT(100)
DOIT(104) DOIT(108) DOIT(112) DOIT(116) DOIT(120) DOIT(124);
p += 128;
}
}
}
#undef DOIT
void
rdwr(iter_t iterations, void *cookie)
{
tsd_t *ts = (tsd_t *)cookie;
register TYPE *lastone = ts->lastone;
register int sum = 0;
while (iterations-- > 0) {
register TYPE *p = ts->buf;
while (p <= lastone) {
#define DOIT(i) sum += p[i]; p[i] = 1;
DOIT(0) DOIT(4) DOIT(8) DOIT(12) DOIT(16) DOIT(20) DOIT(24)
DOIT(28) DOIT(32) DOIT(36) DOIT(40) DOIT(44) DOIT(48) DOIT(52)
DOIT(56) DOIT(60) DOIT(64) DOIT(68) DOIT(72) DOIT(76)
DOIT(80) DOIT(84) DOIT(88) DOIT(92) DOIT(96) DOIT(100)
DOIT(104) DOIT(108) DOIT(112) DOIT(116) DOIT(120) DOIT(124);
p += 128;
}
}
use_int(sum);
}
#undef DOIT
void
mcp(iter_t iterations, void *cookie)
{
tsd_t *ts = (tsd_t *)cookie;
register TYPE *lastone = ts->lastone;
TYPE* p_save = NULL;
while (iterations-- > 0) {
register TYPE *p = ts->buf;
register TYPE *dst = ts->buf2;
while (p <= lastone) {
#define DOIT(i) dst[i] = p[i];
DOIT(0) DOIT(4) DOIT(8) DOIT(12) DOIT(16) DOIT(20) DOIT(24)
DOIT(28) DOIT(32) DOIT(36) DOIT(40) DOIT(44) DOIT(48) DOIT(52)
DOIT(56) DOIT(60) DOIT(64) DOIT(68) DOIT(72) DOIT(76)
DOIT(80) DOIT(84) DOIT(88) DOIT(92) DOIT(96) DOIT(100)
DOIT(104) DOIT(108) DOIT(112) DOIT(116) DOIT(120) DOIT(124);
p += 128;
dst += 128;
}
p_save = p;
}
}
#undef DOIT
void
fwr(iter_t iterations, void *cookie)
{
tsd_t *ts = (tsd_t *)cookie;
register TYPE *lastone = ts->lastone;
TYPE* p_save = NULL;
while (iterations-- > 0) {
register TYPE *p = ts->buf;
while (p <= lastone) {
#define DOIT(i) p[i]=
DOIT(0) DOIT(1) DOIT(2) DOIT(3) DOIT(4) DOIT(5) DOIT(6)
DOIT(7) DOIT(8) DOIT(9) DOIT(10) DOIT(11) DOIT(12)
DOIT(13) DOIT(14) DOIT(15) DOIT(16) DOIT(17) DOIT(18)
DOIT(19) DOIT(20) DOIT(21) DOIT(22) DOIT(23) DOIT(24)
DOIT(25) DOIT(26) DOIT(27) DOIT(28) DOIT(29) DOIT(30)
DOIT(31) DOIT(32) DOIT(33) DOIT(34) DOIT(35) DOIT(36)
DOIT(37) DOIT(38) DOIT(39) DOIT(40) DOIT(41) DOIT(42)
DOIT(43) DOIT(44) DOIT(45) DOIT(46) DOIT(47) DOIT(48)
DOIT(49) DOIT(50) DOIT(51) DOIT(52) DOIT(53) DOIT(54)
DOIT(55) DOIT(56) DOIT(57) DOIT(58) DOIT(59) DOIT(60)
DOIT(61) DOIT(62) DOIT(63) DOIT(64) DOIT(65) DOIT(66)
DOIT(67) DOIT(68) DOIT(69) DOIT(70) DOIT(71) DOIT(72)
DOIT(73) DOIT(74) DOIT(75) DOIT(76) DOIT(77) DOIT(78)
DOIT(79) DOIT(80) DOIT(81) DOIT(82) DOIT(83) DOIT(84)
DOIT(85) DOIT(86) DOIT(87) DOIT(88) DOIT(89) DOIT(90)
DOIT(91) DOIT(92) DOIT(93) DOIT(94) DOIT(95) DOIT(96)
DOIT(97) DOIT(98) DOIT(99) DOIT(100) DOIT(101) DOIT(102)
DOIT(103) DOIT(104) DOIT(105) DOIT(106) DOIT(107)
DOIT(108) DOIT(109) DOIT(110) DOIT(111) DOIT(112)
DOIT(113) DOIT(114) DOIT(115) DOIT(116) DOIT(117)
DOIT(118) DOIT(119) DOIT(120) DOIT(121) DOIT(122)
DOIT(123) DOIT(124) DOIT(125) DOIT(126) DOIT(127) 1;
p += 128;
}
p_save = p;
}
}
#undef DOIT
void
frd(iter_t iterations, void *cookie)
{
tsd_t *ts = (tsd_t *)cookie;
register int sum = 0;
register TYPE *lastone = ts->lastone;
while (iterations-- > 0) {
register TYPE *p = ts->buf;
while (p <= lastone) {
sum +=
#define DOIT(i) p[i]+
DOIT(0) DOIT(1) DOIT(2) DOIT(3) DOIT(4) DOIT(5) DOIT(6)
DOIT(7) DOIT(8) DOIT(9) DOIT(10) DOIT(11) DOIT(12)
DOIT(13) DOIT(14) DOIT(15) DOIT(16) DOIT(17) DOIT(18)
DOIT(19) DOIT(20) DOIT(21) DOIT(22) DOIT(23) DOIT(24)
DOIT(25) DOIT(26) DOIT(27) DOIT(28) DOIT(29) DOIT(30)
DOIT(31) DOIT(32) DOIT(33) DOIT(34) DOIT(35) DOIT(36)
DOIT(37) DOIT(38) DOIT(39) DOIT(40) DOIT(41) DOIT(42)
DOIT(43) DOIT(44) DOIT(45) DOIT(46) DOIT(47) DOIT(48)
DOIT(49) DOIT(50) DOIT(51) DOIT(52) DOIT(53) DOIT(54)
DOIT(55) DOIT(56) DOIT(57) DOIT(58) DOIT(59) DOIT(60)
DOIT(61) DOIT(62) DOIT(63) DOIT(64) DOIT(65) DOIT(66)
DOIT(67) DOIT(68) DOIT(69) DOIT(70) DOIT(71) DOIT(72)
DOIT(73) DOIT(74) DOIT(75) DOIT(76) DOIT(77) DOIT(78)
DOIT(79) DOIT(80) DOIT(81) DOIT(82) DOIT(83) DOIT(84)
DOIT(85) DOIT(86) DOIT(87) DOIT(88) DOIT(89) DOIT(90)
DOIT(91) DOIT(92) DOIT(93) DOIT(94) DOIT(95) DOIT(96)
DOIT(97) DOIT(98) DOIT(99) DOIT(100) DOIT(101) DOIT(102)
DOIT(103) DOIT(104) DOIT(105) DOIT(106) DOIT(107)
DOIT(108) DOIT(109) DOIT(110) DOIT(111) DOIT(112)
DOIT(113) DOIT(114) DOIT(115) DOIT(116) DOIT(117)
DOIT(118) DOIT(119) DOIT(120) DOIT(121) DOIT(122)
DOIT(123) DOIT(124) DOIT(125) DOIT(126) p[127];
p += 128;
}
}
use_int(sum);
}
#undef DOIT
void
fcp(iter_t iterations, void *cookie)
{
tsd_t *ts = (tsd_t *)cookie;
register TYPE *lastone = ts->lastone;
while (iterations-- > 0) {
register TYPE *p = ts->buf;
register TYPE *dst = ts->buf2;
while (p <= lastone) {
#define DOIT(i) dst[i]=p[i];
DOIT(0) DOIT(1) DOIT(2) DOIT(3) DOIT(4) DOIT(5) DOIT(6)
DOIT(7) DOIT(8) DOIT(9) DOIT(10) DOIT(11) DOIT(12)
DOIT(13) DOIT(14) DOIT(15) DOIT(16) DOIT(17) DOIT(18)
DOIT(19) DOIT(20) DOIT(21) DOIT(22) DOIT(23) DOIT(24)
DOIT(25) DOIT(26) DOIT(27) DOIT(28) DOIT(29) DOIT(30)
DOIT(31) DOIT(32) DOIT(33) DOIT(34) DOIT(35) DOIT(36)
DOIT(37) DOIT(38) DOIT(39) DOIT(40) DOIT(41) DOIT(42)
DOIT(43) DOIT(44) DOIT(45) DOIT(46) DOIT(47) DOIT(48)
DOIT(49) DOIT(50) DOIT(51) DOIT(52) DOIT(53) DOIT(54)
DOIT(55) DOIT(56) DOIT(57) DOIT(58) DOIT(59) DOIT(60)
DOIT(61) DOIT(62) DOIT(63) DOIT(64) DOIT(65) DOIT(66)
DOIT(67) DOIT(68) DOIT(69) DOIT(70) DOIT(71) DOIT(72)
DOIT(73) DOIT(74) DOIT(75) DOIT(76) DOIT(77) DOIT(78)
DOIT(79) DOIT(80) DOIT(81) DOIT(82) DOIT(83) DOIT(84)
DOIT(85) DOIT(86) DOIT(87) DOIT(88) DOIT(89) DOIT(90)
DOIT(91) DOIT(92) DOIT(93) DOIT(94) DOIT(95) DOIT(96)
DOIT(97) DOIT(98) DOIT(99) DOIT(100) DOIT(101) DOIT(102)
DOIT(103) DOIT(104) DOIT(105) DOIT(106) DOIT(107)
DOIT(108) DOIT(109) DOIT(110) DOIT(111) DOIT(112)
DOIT(113) DOIT(114) DOIT(115) DOIT(116) DOIT(117)
DOIT(118) DOIT(119) DOIT(120) DOIT(121) DOIT(122)
DOIT(123) DOIT(124) DOIT(125) DOIT(126) DOIT(127)
p += 128;
dst += 128;
}
}
}
void
loop_bzero(iter_t iterations, void *cookie)
{
tsd_t *ts = (tsd_t *)cookie;
register TYPE *p = ts->buf;
register size_t N = ts->N;
while (iterations-- > 0) {
bzero(p, N);
}
}
void
loop_bcopy(iter_t iterations, void *cookie)
{
tsd_t *ts = (tsd_t *)cookie;
register TYPE *p = ts->buf;
register TYPE *dst = ts->buf2;
register size_t N = ts->N;
while (iterations-- > 0) {
bcopy(p,dst,N);
}
}
#pragma mark libmicro routines
int
benchmark_initbatch(void *tsd)
{
tsd_t *ts = (tsd_t *)tsd;
ts->buf = (TYPE *)valloc(ts->nbytes);
ts->buf2_orig = NULL;
ts->lastone = (TYPE*)ts->buf - 1;
ts->lastone = (TYPE*)((char *)ts->buf + ts->nbytes - 512);
ts->N = ts->nbytes;
if (!ts->buf) {
perror("malloc");
exit(1);
}
bzero((void*)ts->buf, ts->nbytes);
if (ts->need_buf2 == 1) {
ts->buf2_orig = ts->buf2 = (TYPE *)valloc(ts->nbytes + 2048);
if (!ts->buf2) {
perror("malloc");
exit(1);
}
if (ts->aligned) {
char *tmp = (char *)ts->buf2;
tmp += 2048 - 128;
ts->buf2 = (TYPE *)tmp;
}
}
return (0);
}
int
benchmark_finirun()
{
return (0);
}
int
benchmark_init()
{
(void) sprintf(lm_optstr, "p:w:n:s:x:");
lm_tsdsize = sizeof (tsd_t);
opt_what = (char *)malloc(30);
(void) sprintf(lm_usage,
" [-p <parallelism>]\n"
" [-w <warmup>]\n"
" [-n <repetitions>]\n"
" -s <size>\n"
" <size> must be larger than 512"
" -x what\n"
" what: rd wr rdwr cp fwr frd fcp bzero bcopy\n"
" [conflict] -- unknown option?\n"
);
return (0);
}
int
benchmark_fini()
{
free(opt_what);
return (0);
}
int
benchmark_finibatch(void *tsd)
{
return (0);
}
char *
benchmark_result()
{
static char result = '\0';
return (&result);
}
int
benchmark_finiworker(void *tsd)
{
tsd_t *ts = (tsd_t *)tsd;
free(ts->buf);
if (ts->buf2_orig) free(ts->buf2_orig);
return (0);
}
int
benchmark_optswitch(int opt, char *optarg)
{
switch (opt) {
case 'p':
optp = sizetoint(optarg);
if (optp <= 0)
return (-1);
break;
case 'w':
optw = sizetoint(optarg);
break;
case 'n':
optn = sizetoint(optarg);
break;
case 's':
opt_size = sizetoint(optarg);
break;
case 'x':
strcpy(opt_what, optarg);
break;
default:
return(-1);
break;
}
return (0);
}
int
benchmark_initworker(void *tsd)
{
tsd_t *ts = (tsd_t *)tsd;
ts->parallel = optp;
ts->warmup = optw;
ts->repetitions = optn;
return (0);
}
int
benchmark_initrun()
{
return (0);
}
int
benchmark(void *tsd, result_t *res)
{
tsd_t *ts = (tsd_t *)tsd;
size_t nbytes;
int i;
ts->overhead = 0;
ts->aligned = ts->need_buf2 = 0;
nbytes = ts->nbytes = opt_size;
if (ts->nbytes < 512) {
return(-1);
}
if (STREQ(opt_what, "cp") ||
STREQ(opt_what, "fcp") || STREQ(opt_what, "bcopy")) {
ts->need_buf2 = 1;
}
for (i = 0 ; i < lm_optB ; i++)
{
if (STREQ(opt_what, "rd")) {
rd( ts->repetitions, tsd );
} else if (STREQ(opt_what, "wr")) {
wr( ts->repetitions, tsd );
} else if (STREQ(opt_what, "rdwr")) {
rdwr( ts->repetitions, tsd );
} else if (STREQ(opt_what, "cp")) {
mcp( ts->repetitions, tsd );
} else if (STREQ(opt_what, "frd")) {
frd( ts->repetitions, tsd );
} else if (STREQ(opt_what, "fwr")) {
fwr( ts->repetitions, tsd );
} else if (STREQ(opt_what, "fcp")) {
fcp( ts->repetitions, tsd );
} else if (STREQ(opt_what, "bzero")) {
loop_bzero( ts->repetitions, tsd );
} else if (STREQ(opt_what, "bcopy")) {
loop_bcopy( ts->repetitions, tsd );
} else {
return(-1);
}
}
res->re_count = i;
return (0);
}