/* 
   iobasic.c
   
   Run as: iobasic <n>

   What is does: allocates an array of n integegers, and traverses the
   array in sequential vs random order.


 */

#include <stdio.h> 
#include <time.h> 
#include <assert.h> 
#include <stdlib.h> 

#define PRINT if(0)

int main(int argc, char** argv) {

  clock_t  t1, t2; 

  //need to run as: iobasic <n>  
  if (argc !=2)  {
    printf("usage: %s [n]\n", argv[0]);
    exit(1); 
  }

  //convert the argument to a long and print it 
  long n = atol(argv[1]); 
  printf("n=%ld (%.1f G) ints which require  %.1f GB RAM\n", 
         n, 
         (float)n/(1<<30), 
         (float)n*sizeof(int)/(1<<30)); 


  //allocate  and initialize an array of n ints 
  t1 = clock(); 
  printf("%30s", "allocate and initialize a: "); 
  int* a = (int*)malloc(n * sizeof(int)); 
  assert(a); 
  for (long i=0; i<n; i++) {
    a[i]=i; 
  } 
  t2 = clock(); 
  printf("time elapsed %.3f seconds\n", (double)(t2-t1)/CLOCKS_PER_SEC); 
  

  //SEQUENTIAL ACCESS ARRAY A
  int sum = 0; 
  t1 = clock(); 
  printf("%30s", "sequential access: \n"); 
  for (long i=0; i<n; i++)  {
    sum =(sum + a[i])%2; 
    
    //print % progress
    PRINT {if (i% (n/100) ==0) printf("%d %% ", (int) (i/(n/100))); fflush(stdout);}
  }
  t2 = clock(); 
  printf("\n%30s time elapsed %.3f seconds\n", " ", (double)(t2-t1)/CLOCKS_PER_SEC); 



  //RANDOM ACCESS ARRAY A
  t1 = clock(); 
  printf("%30s", "random access: \n"); 
  for (long i=0; i<n; i++) {
    //generate a random index in 0..n
    long  k = random() % n; 
    sum =(sum + a[k])%2; 
  
    //print % progress
    PRINT  { if (i% (n/100) ==0) printf("%d %% ", (int) (i/(n/100)));fflush(stdout);}
  } 
  t2 = clock(); 
  printf("\n%30s time elapsed %.3f seconds\n"," ",  (double)(t2-t1)/CLOCKS_PER_SEC); 
  
  return 0; 
}