# 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 中的實驗