1 //**************************************************************************
2 // Multi-threaded Matrix Multiply benchmark
3 //--------------------------------------------------------------------------
4 // TA : Christopher Celio
5 // Student:
6 //
7 //
8 // This benchmark multiplies two 2-D arrays together and writes the results to
9 // a third vector. The input data (and reference data) should be generated
10 // using the matmul_gendata.pl perl script and dumped to a file named
11 // dataset.h.
14 // print out arrays, etc.
15 //#define DEBUG
17 //--------------------------------------------------------------------------
18 // Includes
20 #include <string.h>
21 #include <stdlib.h>
22 #include <stdio.h>
25 //--------------------------------------------------------------------------
26 // Input/Reference Data
28 typedef double data_t;
29 #include "dataset.h"
32 //--------------------------------------------------------------------------
33 // Basic Utilities and Multi-thread Support
35 __thread unsigned long coreid;
36 unsigned long ncores;
37 #define ncores ncores
39 #include "util.h"
41 #define stringify_1(s) #s
42 #define stringify(s) stringify_1(s)
43 #define stats(code) do { \
44 unsigned long _c = -rdcycle(), _i = -rdinstret(); \
45 code; \
46 _c += rdcycle(), _i += rdinstret(); \
47 if (coreid == 0) \
48 printf("%s: %ld cycles, %ld.%ld cycles/iter, %ld.%ld CPI\n", \
49 stringify(code), _c, _c/DIM_SIZE/DIM_SIZE/DIM_SIZE, 10*_c/DIM_SIZE/DIM_SIZE/DIM_SIZE%10, _c/_i, 10*_c/_i%10); \
50 } while(0)
52 //--------------------------------------------------------------------------
53 // matmul function
55 // single-thread, naive version
56 void __attribute__((noinline)) matmul_naive(const int lda, const data_t A[], const data_t B[], data_t C[] )
57 {
58 int i, j, k;
60 if (coreid > 0)
61 return;
63 for ( i = 0; i < lda; i++ )
64 for ( j = 0; j < lda; j++ )
65 {
66 for ( k = 0; k < lda; k++ )
67 {
68 C[i + j*lda] += A[j*lda + k] * B[k*lda + i];
69 }
70 }
72 }
76 void __attribute__((noinline)) matmul(const int lda, const data_t A[], const data_t B[], data_t C[] )
77 {
79 // ***************************** //
80 // **** ADD YOUR CODE HERE ***** //
81 // ***************************** //
82 //
83 // feel free to make a separate function for MI and MSI versions.
85 }
87 //--------------------------------------------------------------------------
88 // Main
89 //
90 // all threads start executing thread_entry(). Use their "coreid" to
91 // differentiate between threads (each thread is running on a separate core).
93 void thread_entry(int cid, int nc)
94 {
95 coreid = cid;
96 ncores = nc;
98 // static allocates data in the binary, which is visible to both threads
99 static data_t results_data[ARRAY_SIZE];
102 // Execute the provided, naive matmul
103 barrier();
104 stats(matmul_naive(DIM_SIZE, input1_data, input2_data, results_data); barrier());
107 // verify
108 int res = verifyDouble(ARRAY_SIZE, results_data, verify_data);
109 if (res)
110 exit(res);
112 #if 0
113 // clear results from the first trial
114 size_t i;
115 if (coreid == 0)
116 for (i=0; i < ARRAY_SIZE; i++)
117 results_data[i] = 0;
118 barrier();
121 // Execute your faster matmul
122 barrier();
123 stats(matmul(DIM_SIZE, input1_data, input2_data, results_data); barrier());
125 #ifdef DEBUG
126 printArray("results:", ARRAY_SIZE, results_data);
127 printArray("verify :", ARRAY_SIZE, verify_data);
128 #endif
130 // verify
131 res = verify(ARRAY_SIZE, results_data, verify_data);
132 if (res)
133 exit(res);
134 barrier();
135 #endif
137 exit(0);
138 }