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


  #define get_ticks(var) { \
      unsigned int __a, __d; \
      asm volatile("rdtsc" : "=a" (__a), "=d" (__d)); \
      var = ((unsigned long) __a) | (((unsigned long) __d) << 32); \
  } while(0)


int main(int argc, char *argv[] )
{
   int i, j, n, m;
   double *B, *C, *D;
   double *E, *F, *G;

   double timer;
   unsigned long ticks0, ticks1; 

   
   if(argc < 3){
      printf("pass me 2 arguments!\n");
      return( -1 );
   }
   else
      {
	 m = atoi(argv[1]);
	 n = atoi(argv[2]);
      }
   
   B = (double *) malloc( m*n * sizeof(double) );
   C = (double *) malloc( m*n * sizeof(double) );
   D = (double *) malloc( m*n * sizeof(double) );
   E = (double *) malloc( m*n * sizeof(double) );
   F = (double *) malloc( m*n * sizeof(double) );
   G = (double *) malloc( m*n * sizeof(double) );

   for( i=0; i<m; i++ )
      for( j=0; j<n; j++ )
	 {
	    B[j*m+i] =   10.0001*j+i;
	    C[j*m+i] = -(10.0001*j+i);
	    E[j*m+i] =   10.0001*j+i;
	    F[j*m+i] = -(10.0001*j+i);
	    //printf("idx=%d \tval=%lf\n", j*m+i, 10.0001*j+i);
	 }

  timer = ((double) clock ())/CLOCKS_PER_SEC;
  get_ticks(ticks0);   

  for( i=0; i<m; i++ )
     for( j=0; j<n; j++ )
	{
	   D[j*m+i] = B[j*m+i] + C[j*m+i];
	}

  get_ticks(ticks1); 
  unsigned long ticks = ticks1 - ticks0; 

  
  /* for( i=0; i<m; i++ ) */
  /*    for( j=0; j<n; j++ ) */
  /* 	printf("D[%d]=%.16lf\n", j*m+i, D[j*m+i]); */


  double c_time = (((double) clock ())/CLOCKS_PER_SEC) - timer;
  
  // printf(" 1) C timer= %.5lf\n", c_time);
  printf(" 1) ASM timer= %.5ld\n", ticks );
  // printf(" 1) ratio = %.5g\n", (double) ticks/c_time );


  timer = ((double) clock ())/CLOCKS_PER_SEC;
  get_ticks(ticks0);   

  for( i=0; i<m; i++ )
     for( j=0; j<n; j++ )
	{
	   G[j+i*n] = E[j+i*n] + F[j+i*n];
	}

  get_ticks(ticks1); 
  ticks = ticks1 - ticks0; 
  c_time = (((double) clock ())/CLOCKS_PER_SEC) - timer;
  
  // printf(" 2) C timer= %.5lf\n", c_time);
  printf(" 2) ASM timer= %.5ld\n", ticks );

  
  /* for( i=0; i<m; i++ ) */
  /*    for( j=0; j<n; j++ ) */
  /* 	printf("G[%d]=%.16lf\n", j*m+i, G[j*m+i]); */

  
  return 0;
}
   
