// This file is part of BOINC.
// http://boinc.berkeley.edu
// Copyright (C) 2008 University of California
//
// BOINC is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License
// as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
//
// BOINC is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with BOINC. If not, see .
// Memory bandwidth benchmark derived from STREAM. Original copyright
// notice follows. Notice that we cannot call our results "STREAM
// benchmark results"
// Original Copyright Notice:
/*-----------------------------------------------------------------------*/
/* Program: Stream */
/* Revision: Id: stream.c,v 5.6 2005/10/04 00:19:59 mccalpin */
/* Original code developed by John D. McCalpin */
/* Programmers: John D. McCalpin */
/* Joe R. Zagar */
/* */
/* This program measures memory transfer rates in MB/s for simple */
/* computational kernels coded in C. */
/*-----------------------------------------------------------------------*/
/* Copyright 1991-2005: John D. McCalpin */
/*-----------------------------------------------------------------------*/
/* License: */
/* 1. You are free to use this program and/or to redistribute */
/* this program. */
/* 2. You are free to modify this program for your own use, */
/* including commercial use, subject to the publication */
/* restrictions in item 3. */
/* 3. You are free to publish results obtained from running this */
/* program, or from works that you derive from this program, */
/* with the following limitations: */
/* 3a. In order to be referred to as "STREAM benchmark results", */
/* published results must be in conformance to the STREAM */
/* Run Rules, (briefly reviewed below) published at */
/* http://www.cs.virginia.edu/stream/ref.html */
/* and incorporated herein by reference. */
/* As the copyright holder, John McCalpin retains the */
/* right to determine conformity with the Run Rules. */
/* 3b. Results based on modified source code or on runs not in */
/* accordance with the STREAM Run Rules must be clearly */
/* labelled whenever they are published. Examples of */
/* proper labelling include: */
/* "tuned STREAM benchmark results" */
/* "based on a variant of the STREAM benchmark code" */
/* Other comparable, clear and reasonable labelling is */
/* acceptable. */
/* 3c. Submission of results to the STREAM benchmark web site */
/* is encouraged, but not required. */
/* 4. Use of this program or creation of derived works based on this */
/* program constitutes acceptance of these licensing restrictions. */
/* 5. Absolutely no warranty is expressed or implied. */
/*-----------------------------------------------------------------------*/
# include
# include
# include
# include
# include
# include
# include
static int N=64;
static const int NTIMES(10);
static const int OFFSET(0);
static double avgtime[4] = {0}, maxtime[4] = {0},
mintime[4] = {FLT_MAX,FLT_MAX,FLT_MAX,FLT_MAX};
static char *label[4] = {"Copy: ", "Scale: ",
"Add: ", "Triad: "};
static double bytes[4] = {
2 * sizeof(double) * N,
2 * sizeof(double) * N,
3 * sizeof(double) * N,
3 * sizeof(double) * N
};
extern double mysecond();
extern double checktick();
extern void checkSTREAMresults(double *a,double *b, double *c);
void mem_bw(double &avg_bw, double &cache_size) {
avg_bw=0;
double *a=(double *)malloc((N+OFFSET)*sizeof(double));
double *b=(double *)malloc((N+OFFSET)*sizeof(double));
double *c=(double *)malloc((N+OFFSET)*sizeof(double));
double quantum=checktick();
int BytesPerWord;
register int j, k;
double scalar, t, times[4][NTIMES];
double rv=0;
double tt[30],t_max;
int cache_ratio=1,cache_level=1;
int i=0;
int check_cache=(cache_size==0);
do {
N*=2;
a=(double *)realloc(a,(N+OFFSET)*sizeof(double));
b=(double *)realloc(b,(N+OFFSET)*sizeof(double));
c=(double *)realloc(c,(N+OFFSET)*sizeof(double));
if ( !a || !b || !c ) return;
for (j=0; j
double mysecond() {
struct timeval tp;
struct timezone tzp;
int i;
i = gettimeofday(&tp,&tzp);
return ( (double) tp.tv_sec + (double) tp.tv_usec * 1.e-6 );
}
void checkSTREAMresults (double *a, double *b, double *c) {
double aj,bj,cj,scalar;
double asum,bsum,csum;
double epsilon;
int j,k;
/* reproduce initialization */
aj = 1.0;
bj = 2.0;
cj = 0.0;
/* a[] is modified during timing check */
aj = 2.0E0 * aj;
/* now execute timing loop */
scalar = 3.0;
for (k=0; k= 0 ? (a) : -(a))
#endif
epsilon = 1.e-8;
if (abs(aj-asum)/asum > epsilon) {
printf ("Failed Validation on array a[]\n");
printf (" Expected : %f \n",aj);
printf (" Observed : %f \n",asum);
} else if (abs(bj-bsum)/bsum > epsilon) {
printf ("Failed Validation on array b[]\n");
printf (" Expected : %f \n",bj);
printf (" Observed : %f \n",bsum);
} else if (abs(cj-csum)/csum > epsilon) {
printf ("Failed Validation on array c[]\n");
printf (" Expected : %f \n",cj);
printf (" Observed : %f \n",csum);
} else {
printf ("Solution Validates\n");
}
}
#ifdef STREAM_TEST
int main() {
double cache_size=0;
double avg_bw=0;
mem_bw(avg_bw,cache_size);
printf("Average bandwidth=%f MB/s\n",avg_bw/1024/1024);
printf("Cache Size=%f kB\n",cache_size/1024);
}
#endif