Benchmark
Run the benchmark and plot the results as described below.
Benchmark Program
#include <stddef.h> #include <stdio.h> #include <stdlib.h> #include <sys/times.h> #include <unistd.h> //-- timer for benchmarks ------------------------------------------------------ double walltime() { struct tms ts; static double ClockTick=0.0; if (ClockTick==0.0) { ClockTick = 1.0 / ((double) sysconf(_SC_CLK_TCK)); } return ((double) times(&ts)) * ClockTick; } //------------------------------------------------------------------------------ void initMatrix(size_t m, size_t n, double *A, ptrdiff_t incRow, ptrdiff_t incCol) { for (size_t i=0; i<m; ++i) { for (size_t j=0; j<n; ++j) { A[i*incRow+j*incCol] = i*n+j+1; } } } void printMatrix(size_t m, size_t n, const double *A, ptrdiff_t incRow, ptrdiff_t incCol) { for (size_t i=0; i<m; ++i) { for (size_t j=0; j<n; ++j) { printf("%10.3lf", A[i*incRow+j*incCol]); } printf("\n"); } printf("\n"); } #ifndef MAX_ROWS #define MAX_ROWS 5000 #endif #ifndef MAX_COLS #define MAX_COLS 5000 #endif int main() { double *A = (double *) malloc(MAX_ROWS*MAX_COLS*sizeof(double)); printf("%6s %6s ", "#m", "n"); printf("%12s ", "t (col major)"); printf("%12s ", "t (row major)"); printf("\n"); for (size_t m=256, n=256; m<=MAX_ROWS && n<=MAX_COLS; m+=16, n+=16) { printf("%6zu %6zu ", m, n); size_t incRow, incCol; double t0, t; // Store A col major incRow = 1; incCol = m; t0 = walltime(); initMatrix(m, n, A, incRow, incCol); t = walltime() - t0; printf("%12.2lf ", t); // Store A row major incRow = n; incCol = 1; t0 = walltime(); initMatrix(m, n, A, incRow, incCol); t = walltime() - t0; printf("%12.2lf ", t); printf("\n"); } free(A); return 0; }
Compile and Run
$shell> gcc -Wall -std=c99 -O3 -o matrix_bench matrix_bench.c $shell> matrix_bench > bench.dat $shell>
Gnuplot Script
We will use the following script for Gnuplot.
set terminal svg size 900, 500 set output "bench.svg" set xlabel "Matrix Dimensions (m=n)" set ylabel "Time elapsed" set title "Matrix Initialization" set key outside set pointsize 0.5 plot "bench.dat" using 1:3 with linespoints lt 2 lw 3 title "col major", \ "bench.dat" using 1:4 with linespoints lt 3 lw 3 title "row major"
Generate the Plot
Running
$shell> gnuplot bench.gps $shell>
creates the plot
in file bench.svg