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
#include <stdio.h>
#define LONGITUD 1024
#define VECES 10

unsigned long timestamp(){
  /* RDTSCP entrega el valor del contador de tiempo del CPU (TSC), obligando */
  /* a la serializaciĆ³n (evitando el reordenamiento de instrucciones). */
  /* Siendo un valor de 64 bits, se recupera de los registros RDX y RAX. */
  /* */
  /* Referencias: */
  /* https://ccsl.carleton.ca/~jamuir/rdtscpm1.pdf */
  /* http://www.strchr.com/performance_measurements_with_rdtsc */
  /* https://stackoverflow.com/questions/12631856/difference-between-rdtscp-rdtsc-memory-and-cpuid-rdtsc */
  long tsc;
  asm volatile("rdtscp; "         /* Lectura serializada del TSC
               "shl $32, %%rdx; " /* Recorre 32 bits bajos de RDX a izq. */
               "or %%rdx, %%rax"  /* Combina RDX y RAX */
               : "=a"(tsc)        /* Obtiene el valor en la variable tsc */
               :
               : "%rcx", "%rdx"   /* Registros que son afectados */
               );
  return tsc;
}

void llena_arreglo(int modo) {
  int data[LONGITUD][LONGITUD];
  int x, y;
  for (x=0; x < LONGITUD; x++)
    for (y=0; y < LONGITUD; y++)
      if (modo)
        data[y][x] = 1;
      else
        data[x][y] = 1;
}

void main(){
  unsigned long inicio, fin, prom_h, prom_v;
  printf( "Usando %d bytes de memoria\n", LONGITUD*LONGITUD*sizeof(int));
  prom_h = 0;
  prom_v = 0;

  for (int i=0; i < VECES; i++) {
    inicio = timestamp();
    llena_arreglo(0);
    fin = timestamp();
    prom_h += (fin-inicio);
    printf("De %lu a %lu: %lu\n", inicio, fin, fin - inicio);
  }
  printf("Promedio (horizontal): %lu\n", prom_h / VECES);

  printf("=========\n");
  for (int i=0; i < VECES; i++) {
    inicio = timestamp();
    llena_arreglo(1);
    fin = timestamp();
    prom_v += (fin-inicio);
    printf("De %lu a %lu: %lu\n", inicio, fin, fin - inicio);
  }
  printf("Promedio (vertical): %lu\n", prom_v / VECES);
  printf("\nRelaciĆ³n (horiz / vert): %f\n", (float) prom_h / prom_v);
}