#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include "util.h"

#define N 1000
#define M 1000

void init(int32_t **matrix) {
    for (size_t i = 0; i < N; i++) {
        matrix[i] = malloc(M * sizeof(int32_t));
    }
}

void reset(int32_t **matrix) {
    for (size_t i = 0; i < N; i++) {
        for (size_t j = 0; j < M; j++) {
            matrix[i][j] = i * j;
            flush_cache_line(&matrix[i][j]);
        }
    }
}

uint64_t time_access_pattern_1(int32_t **matrix) {
    uint64_t total_cycles = 0;
    for (size_t i = 0; i < N; i++) {
        for (size_t j = 0; j < M; j++) {
            total_cycles += time_read(&matrix[i][j]);
        }
    }
    return total_cycles;
}

uint64_t time_access_pattern_2(int32_t **matrix) {
    uint64_t total_cycles = 0;
    for (size_t j = 0; j < M; j++) {
        for (size_t i = 0; i < N; i++) {
            total_cycles += time_read(&matrix[i][j]);
        }
    }
    return total_cycles;
}

int main(void) {
    int32_t **matrix = calloc(N, sizeof(int32_t *));
    init(matrix);

    reset(matrix);
    uint64_t cycles1 = time_access_pattern_1(matrix);

    reset(matrix);
    uint64_t cycles2 = time_access_pattern_2(matrix);

    printf("%lu vs. %lu\n", cycles1, cycles2);
}
