#include "bandwidth.h"

void membandwidth(){
	void * retval;
        struct timeval starttime,endtime;
        double te, test1, test2, test3;
        register double t, t2;
	int long_size=sizeof(long);
	register long asize = memtotal * 1024 * 1024 / long_size;
	register long array_bytes=asize*long_size;
        register long block_size;
	register long *a;
	register long *b;
	memtotal /= 2;
	printf ("Running Memory Bandwidth Tests:\n\n");
	printf ( "\tallocating %lfMB a peice (%lfMB total) two zero-initialized memory blocks\n\n", memtotal, memtotal*2); 
	a=calloc(asize, long_size);
	b=calloc(asize, long_size);

	printf ( "\tcopying array a to array b in progessive steps of %lfMB\n", memtotal/64);
	block_size= memtotal/64 * 1024 * 1024 / long_size;
	gettimeofday(&starttime, NULL);
	for(t=0; t<array_bytes; t+=block_size) {
        	retval = memcpy(b,a,t);
        }
	gettimeofday(&endtime, NULL);
        te=((double)(endtime.tv_sec*1000000-starttime.tv_sec*1000000+endtime.tv_usec-starttime.tv_usec))/1000000;
        
	t2 = 0;
        for(t=0; t<array_bytes; t+=block_size) {
               t2+=t; 
        }
	
	test1 = (t2/1024/1024)/te;
	printf ( "\t\tResult: %lfMB/s\n\n", test1*2);

	printf ( "\tcopying array a to array b in progressive steps of %lfMB\n", memtotal/18);
        block_size=memtotal/18 * 1024 * 1024 / long_size;
	gettimeofday(&starttime, NULL);
        for(t=0; t<array_bytes; t+=block_size) {
                retval = memcpy(b,a,t);
        }
        gettimeofday(&endtime, NULL); 
        te=((double)(endtime.tv_sec*1000000-starttime.tv_sec*1000000+endtime.tv_usec-starttime.tv_usec))/1000000;
        t2 = 0;
        for(t=0; t<array_bytes; t+=block_size) {
               t2+=t;
        }
	test2 = (t2/1024/1024)/te;
        printf ( "\t\tResult: %lfMB/s\n\n", test2*2);




        printf ( "\tcopying array a to array b in progressive steps of %lfMB\n", memtotal/4);
        block_size=memtotal/4 * 1024 * 1024 / long_size;
        gettimeofday(&starttime, NULL);
        for(t=0; t<array_bytes; t+=block_size) {
                retval = memcpy(b,a,t);
        }
        gettimeofday(&endtime, NULL);
        te=((double)(endtime.tv_sec*1000000-starttime.tv_sec*1000000+endtime.tv_usec-starttime.tv_usec))/1000000;
        t2 = 0;
        for(t=0; t<array_bytes; t+=block_size) {
               t2+=t;
        }
        test3 = (t2/1024/1024)/te;
        printf ( "\t\tResult: %lfMB/s\n\n", test3*2);

	printf ( "\tfreeing arrays\n\n");
	free (a);
	free (b);

	printf ("\taverage read+write mem bandwidth %lfMB/s\n\n", ((test1*2)+(test2*2)+(test3*2))/3);
	printf ( "\tdone.\n\n");

}
