Search code examples
cmallocparameter-passingcpu-cache

Decipher assignment about measuring throughput of L2 cache


I've noticed that a few of my classmates have actually tried asking questions about this same assignment on StackOverflow over the past few days so I'm going to shamelessly copy paste (only) the context of one question that was deleted (but still cached on Google with no answers) to save time. I apologize in advance for that.

Context
I am trying to write a C program that measures the data throughput (MBytes/sec) of the L2 cache of my system. To perform the measurement I have to write a program that copies an array A to an array B, repeated multiple times, and measure the throughput.

Consider at least two scenarios:

  • Both fields fit in the L2 cache
  • The array size is significantly larger than the L2 cache size.

Using memcpy() from string.h to copy the arrays, initialize both arrays with some values (e.g. random numbers using rand()), and repeat at least 100 times, otherwise you do not see a difference.

The array size and number of repeats should be input parameters. One of the array sizes should be half of my L2 cache size.

Question
So based on that context of the assignment I have a good idea of what I need to do because it pretty much tells me straight out. The problem is that we were given some template code to work with and I'm having trouble deciphering parts of it. I would really appreciate it if someone would help me to just figure out what is going on.

The code is:

/* do not add other includes */
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <time.h>
#include <string.h>

double getTime(){
  struct timeval t;
  double sec, msec;

  while (gettimeofday(&t, NULL) != 0);
  sec = t.tv_sec;
  msec = t.tv_usec;

  sec = sec + msec/1000000.0;

  return sec;
}

/* for task 1 only */
void usage(void)
{
    fprintf(stderr, "bandwith [--no_iterations iterations] [--array_size size]\n");
    exit(1);
}

int main (int argc, char *argv[])
{
  double t1, t2; 

  /* variables for task 1 */
  unsigned int size = 1024;
  unsigned int N = 100; 
  unsigned int i;

  /* declare variables; examples, adjust for task */
  int *A;
  int *B;


  /* parameter parsing task 1 */
  for(i=1; i<(unsigned)argc; i++) {
    if (strcmp(argv[i], "--no_iterations") == 0) {
      i++;
      if (i < argc)
        sscanf(argv[i], "%u", &N);
      else
        usage();
    } else if (strcmp(argv[i], "--array_size") == 0) {
      i++;
      if (i < argc)
        sscanf(argv[i], "%u", &size);
      else
        usage();
    } else usage();
  }


  /* allocate memory for arrays; examples, adjust for task */
  A = malloc (size*size * sizeof (int));
  B = malloc (size*size * sizeof (int));



  /* initialise arrray elements */    




  t1 = getTime();

  /* code to be measured goes here */



  t2 = getTime();


  /* output; examples, adjust for task */
  printf("time: %6.2f secs\n",t2 - t1);

  /* free memory; examples, adjust for task */
  free(B);
  free(A);

  return 0;  
}

My questions are:

  • What could the purpose of the usage method be?
  • What is the parameter passing part supposed to be doing because as far as I can tell it will just always lead to usage() and won't take any parameters with the sscanf lines?
  • In this assignment we're meant to record array sizes in KB or MB, and I know that malloc allocates size in bytes and with a size variable value of 1024 would result in 1MB * sizeof(int) (I think at least). In this case would the array size I should record be 1MB or 1MB * sizeof(int)?
  • If parameter passing worked properly and we passed parameters to change the size variable value would the array size always be the size variable squared? Or would the array size be considered to be just the size variable? It seems very unintuitive to malloc size*size instead of just size unless there's something I'm missing about all this.
  • My understanding of measuring the throughput is that I should just multiply the array size by the number of iterations and then divide by the time taken. Can I get any confirmation that this is right?

These are the only hurdles in my understanding of this assignment. Any help would be much appreciated.


Solution

    • What could the purpose of the usage method be?

    The usage function tells you what arguments are supposed to be passed to the program on the command-line.

    • What is the parameter passing part supposed to be doing because as far as I can tell it will just always lead to usage() and won't take any parameters with the sscanf lines?

    It leads the calling the usage() function when an invalid argument is passed to the program.

    Otherwise, it sets the number of iterations to the variable N to the value of the argument no_iterations (default value of 100), and it sets the size of the array to the variable size to the value of the argument array_size (default value of 1024).

    • In this assignment we're meant to record array sizes in KB or MB, and I know that malloc allocates size in bytes and with a size variable value of 1024 would result in 1MB * sizeof(int) (I think at least). In this case would the array size I should record be 1MB or 1MB * sizeof(int)?

    If your size is supposed to be 1 MB, then that is probably what the size should be.

    If you want to make it sure the size is a factor of the size of the data type, then you can do:

    if (size % sizeof(int) != 0)
    {
        size = ((int)(size / sizeof(int))) * sizeof(int);
    }
    
    • If parameter passing worked properly and we passed parameters to change the size variable value would the array size always be the size variable squared? Or would the array size be considered to be just the size variable? It seems very unintuitive to malloc size*size instead of just size unless there's something I'm missing about all this.

    You probably just want to allocate size bytes. Unless you are supposed to be working with matrices, rather than just arrays. In that case, it would be size * size bytes.

    • My understanding of measuring the throughput is that I should just multiply the array size by the number of iterations and then divide by the time taken. Can I get any confirmation that this is right?

    I guess so.