# 2017q1 Homework5 (matrix)
contributed by <`Weinux`>
###### tags: `sysprog2017` `w5` `matrix` `Weinux`
## 相關連結
* [ B10: matrix 作業要求](https://hackmd.io/s/rkrrpHm2e)
* [ matrix_oo 專案](https://github.com/sysprog21/matrix_oo)
* [ github 程式碼](https://github.com/Weinux/matrix_oo)
* [ Matrix Multiplication using SIMD_HackMD](https://hackmd.io/s/Hk-llHEyx)
* [ 你所不知道的C語言:技巧篇](https://hackmd.io/s/HyIdoLnjl)
* [ 作業區](https://hackmd.io/s/ryPKJUm2l)
## 開發環境
* OS:Lubuntu 16.04 LTS
* Linux 系統版本: 4.4.0-63-generic
* Architecture: x86_64
* CPU 作業模式: 32-bit, 64-bit
* Byte Order: Little Endian
* CPU: Intel(R) Core(TM) i5-2410M CPU @ 2.30GHz
* Model name: Intel(R) Core(TM) i5-2410M CPU @ 2.30GHz
* Memory: 6GB (5870MB)
* Cache:
* L1d cache: 32K
* L1i cache: 32K
* L2 cache: 256K
* L3 cache: 3072K
## matrix_oo
**先來看 matrix.h 檔案 :**
* matrix.h 提供了介面 讓矩陣把 `row col 以及 *priv` 等資料封裝在 Matrix 中, 把矩陣運算要有的方法 (e.g., assign equl mul) 將這些方法的 function pointer 封裝在 MatrixAlgo.
```c=12
typedef struct {
int row, col;
void *priv;
} Matrix;
typedef struct {
void (*assign)(Matrix *thiz, Mat4x4);
bool (*equal)(const Matrix *l, const Matrix *r);
bool (*mul)(Matrix *dst, const Matrix *l, const Matrix *r);
} MatrixAlgo;
```
* 如果未來針對其中的方法有不同的實作, 僅需要講指標指到其他的實作就可以更改實作, 而且可以將實作與介面分開.
* 在 matrix_naive.c 中: 建立了 NaiveMatrixProvider 透過 designated initializer 把 `asign equal mul` 的指標指向目前 Naive 版本的實作
```c=46
MatrixAlgo NaiveMatrixProvider = {
.assign = assign,
.equal = equal,
.mul = mul,
};
```
* 因此在主要測試程式 test-matrix.c 中, 有一個 MatrixAlgo* 陣列 `matrix_providers[]` 未來實作 AVX SSE 版本時, 只需要在陣列中加入其他的 provider 就可以在 main 切換不同實作
**一開始的版本**
```c=1
#include "matrix.h"
#include <stdio.h>
MatrixAlgo *matrix_providers[] = {
&NaiveMatrixProvider,
};
int main()
{
MatrixAlgo *algo = matrix_providers[0];
```
**未來可能的版本**
```c=1
#include "matrix.h"
#include <stdio.h>
MatrixAlgo *matrix_providers[] = {
&NaiveMatrixProvider,
&AvxMatrixProvider,
&SseMatrixProvider
};
int main()
{
MatrixAlgo *algo = matrix_providers[0]; // naive version
algo = matrix_providers[1]; // avx version
algo = matrix_providers[2]; // sse version
```
* matrix_oo 中目前只能做
## 待改善項目
* matrix_oo 裡頭只支援 4x4 矩陣的限制,考慮 sub-matrix 和 column-major 來提升 cache 使用率
* 驗證過程需要考慮不同大小的矩陣
* 需要考慮到矩陣乘法的有效性,不是任意矩陣都可相互執行乘法
* 重現 Matrix Multiplication using SIMD 中的實驗