1 /* Memory streaming benchmark */
4 * Copyright (C) 2003-2006 IBM
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of the
9 * License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
22 #define __int64 long long
26 #include <sys/types.h>
36 void *Malloc(size_t sz
);
50 int nmethods
= sizeof(methods
)/sizeof(methods
[0]);
52 int fflag
= 0; // if 0, then just Malloc once; else malloc/free each time
53 int wflag
= 0; // if 1, call SetProcessWorkingSetSize() (WINDOWS ONLY)
54 int sflag
= 0; // if 1, only print averages.
56 int csvflag
= 0; // Print Comma separated list for spreadsheet input.
61 int main(int ac
, char *av
[])
79 if(strrchr(progname
,SLASHC
))
80 progname
= strrchr(progname
,SLASHC
) + 1;
83 if(equal(av
[1], "-f")) {
88 else if(equal(av
[1], "-w")) {
93 else if(equal(av
[1], "-s")) {
98 else if(equal(av
[1], "-p")) {
103 else if(equal(av
[1], "-csv")) {
112 (void)printf("Usage: %s [-f] [-w] [-s] [-p] size cnt [method]\n",progname
);
113 (void)printf("\t-f flag says to malloc and free of the \"cnt\" times.\n");
114 (void)printf("\t-w = set process min and max working set size to \"size\"\n");
115 (void)printf("\t-s = silent; only print averages\n");
116 (void)printf("\t-p = prep; \"freshen\" cache before; -w disables\n");
117 (void)printf("\t-csv = print output in CSV format\n");
119 (void)printf("\tmethods:\n");
120 for(i
= 0; i
< nmethods
; i
++)
121 printf("\t%2d:\t%s\n",i
,methods
[i
]);
128 // Round size up to 4*sizeof(double) bytes.
130 if(size
!= ((size
/ (4*sizeof(double)) ) * (4*sizeof(double)) )) {
131 size
+= (4*sizeof(double));
132 size
/= (4*sizeof(double));
133 size
*= (4*sizeof(double));
135 cnt
= (unsigned)atoik(av
[2]);
138 p1
= (char *)Malloc(size
);
139 p2
= (char *)Malloc(size
);
144 printf("%s ",progname
);
145 if(fflag
) printf("-f ");
146 if(wflag
) printf("-w ");
147 if(sflag
) printf("-s ");
148 if(pflag
) printf("-p ");
149 if(csvflag
) printf("-csv ");
150 printf("%u %u ", size
, cnt
);
161 for(; ac
> 3; ac
--, av
++) {
162 if(isdigit(*av
[3])) method
= *av
[3] - '0';
163 if(method
< 0 || method
>= nmethods
)
167 for(ui
= 0; ui
< cnt
; ui
++) {
169 (void)printf("%s %d %d %-18.18s\t",
170 progname
, size
, cnt
, methods
[method
]);
174 p1
= (char *)Malloc(size
);
175 p2
= (char *)Malloc(size
);
179 (void)memcpy(p1
, p2
, size
);
184 for(j
= 0; j
< size
; j
++)
190 for(j
= 0; j
< size
; j
+= sizeof(short))
196 for(j
= 0; j
< size
; j
+= sizeof(int))
202 for(j
= 0; j
< size
; j
+= sizeof(long))
208 for(j
= 0; j
< size
; j
+= sizeof(__int64
))
214 for(j
= 0; j
< size
; j
+= 4*sizeof(double)) {
233 printf(" %8.6f seconds %8.3f MB/s\n",
235 (double)size
/t
/1000000.);
243 printf("%s,%u,%u,%8.3f,%8.3f\n",
244 methods
[method
],size
,size
*cnt
,tottim
,(double)size
/(tottim
/cnt
)/1000000.);
247 (void)printf("\tAVG: %d %-18.18s\t", size
, methods
[method
]);
248 (void)printf(" %8.3f MB/s\n", (double)size
/(tottim
/cnt
)/1000000.);
256 size_t atoik(char *s
)
263 if(*++s
== 'x' || *s
== 'X') {
271 for(; isxdigit(*s
); s
++) {
274 ret
= base
*ret
+ (toupper(*s
) - 'A');
276 ret
= base
*ret
+ (*s
- '0');
278 ret
= base
*ret
+ (*s
- '0');
282 for(; isalpha(*s
); s
++) {
283 switch(toupper(*s
)) {
284 case 'K': ret
*= 1024; break;
285 case 'M': ret
*= 1024*1024; break;
292 void *Malloc(size_t sz
)
296 p
= (char *)malloc(sz
);
298 (void)printf("malloc(%d) failed\n",sz
);
304 static struct timeval _tstart
, _tend
;
308 gettimeofday(&_tstart
, NULL
);
312 gettimeofday(&_tend
, NULL
);
319 t1
= (double)_tstart
.tv_sec
+ (double)_tstart
.tv_usec
/(1000*1000);
320 t2
= (double)_tend
.tv_sec
+ (double)_tend
.tv_usec
/(1000*1000);