Download c source code

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
// Copyright 2021 Allan Berrocal <allan.berrocal@ucr.ac.cr > and
// Jeisson Hidalgo <jeisson.hidalgo@ucr.ac.cr> CC-BY 4.0.
// Adapted from Mr. Jainam M https://github.com/MJjainam/falseSharing

#define _DEFAULT_SOURCE

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

const size_t ELEMENT_COUNT = 1000;
const size_t FIRST_ELEMENT = 0;
const size_t SECOND_ELEMENT = 1;
const size_t LAST_ELEMENT = ELEMENT_COUNT - 1;
const size_t ITERATION_COUNT = 100000000;

const char* description[] = {
  "sequential(first, second)",
  "sequential(first, last)",
  "concurrent(first, second)",
  "concurrent(first, last)",
};

int* array = NULL;

// Updates an element of the array in a suboptimal manner
void *update_element(void *data) {
  const size_t my_index = (size_t)data;

  for (size_t iteration = 0; iteration < ITERATION_COUNT; ++iteration) {
    array[my_index] += iteration % ELEMENT_COUNT;
  }

  return NULL;
}

void run_sequential(size_t index0, size_t index1) {
  update_element((void*) index0);
  update_element((void*) index1);
}

void run_concurrent(size_t index0, size_t index1) {
  pthread_t thread0, thread1;
  pthread_create(&thread0, NULL, update_element, (void*) index0);
  pthread_create(&thread1, NULL, update_element, (void*) index1);
  pthread_join(thread0, NULL);
  pthread_join(thread1, NULL);
}

int main(int argc, char* argv[]) {
  const int mode = argc >= 2 ? atoi(argv[1]) : 0;
  array = (int*) calloc(ELEMENT_COUNT, sizeof(int));
  assert(array);

  struct timespec start_time, finish_time;
  clock_gettime(CLOCK_REALTIME, &start_time);

  switch (mode) {
    case 0: run_sequential(FIRST_ELEMENT, SECOND_ELEMENT); break;
    case 1: run_sequential(FIRST_ELEMENT, LAST_ELEMENT); break;
    case 2: run_concurrent(FIRST_ELEMENT, SECOND_ELEMENT); break;
    case 3: run_concurrent(FIRST_ELEMENT, LAST_ELEMENT); break;
  }

  clock_gettime(CLOCK_REALTIME, &finish_time);
  double elapsed_time = finish_time.tv_sec - start_time.tv_sec +
    (finish_time.tv_nsec - start_time.tv_nsec) * 1e-9;

  if (mode >= 0 && mode < 4) {
    printf("%.6lfs: %s\n", 1000 * elapsed_time, description[mode]);
  }

  free(array);
  return EXIT_SUCCESS;
}