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
|
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);
}
|