# 2017q1 Homework5 (matrix)
contributed by < `illusion030` >
---
## 開發環境
```
illusion030@illusion030-X550LD:~/Desktop/2017sysprog/matrix_oo$ lscpu
Architecture: x86_64
CPU 作業模式: 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 4
On-line CPU(s) list: 0-3
每核心執行緒數:2
每通訊端核心數:2
Socket(s): 1
NUMA 節點: 1
供應商識別號: GenuineIntel
CPU 家族: 6
型號: 69
Model name: Intel(R) Core(TM) i5-4200U CPU @ 1.60GHz
製程: 1
CPU MHz: 1691.168
CPU max MHz: 2600.0000
CPU min MHz: 800.0000
BogoMIPS: 4589.15
虛擬: VT-x
L1d 快取: 32K
L1i 快取: 32K
L2 快取: 256K
L3 快取: 3072K
NUMA node0 CPU(s): 0-3
```
---
## 重現實驗
* fork [matrix_oo](https://github.com/sysprog21/matrix_oo) 並以其為基礎重現 [Matrix Multiplication using SIMD](https://hackmd.io/s/Hk-llHEyx#) 的實驗
### SSE
* 先將 sse 版本整合過來,發現一個問題是 [Matrix Multiplication using SIMD](https://hackmd.io/s/Hk-llHEyx#) 是用 integer 的矩陣相乘,但是在 [matrix_oo](https://github.com/sysprog21/matrix_oo) 的 naive 版本是用 float 型態的矩陣
* 先用 integer 型態的矩陣相乘實作看看
* 測試結果
```
Execute tests/test-matrix...
naive result equal!!
sse result equal!!
OK!
```
相乘結果是正確的
### 克服 Matrix 大小的限制
* 嘗試克服 Matrix 大小只有 4x4 的限制
* 改成傳入二維陣列
```=vim
static void assign(Matrix *thiz, int row, int col, int **data)
```
* 遇到問題,在`PRIV()`裡需要 malloc 空間給 values,不然會 Segmentation fault
上網查了一下資料
```=vim
if (!(thiz->priv = malloc(thiz->row * thiz->col * sizeof(int))))
return;
if (!(PRIV(thiz)->values = (int **)malloc(row * sizeof(int *))))
return;
for (i = 0; i < thiz->row; i++)
if (!(PRIV(thiz)->values[i] = (int *)malloc(thiz->col * sizeof(int))))
return;
```
* 對 mul 的 dst 也做一樣的事
```=vim
if (!(dst->priv = malloc(l->row * r->col * sizeof(int))))
return false;
if (!(PRIV(dst)->values = (int **)malloc(l->row * sizeof(int *))))
return false;
for (i = 0; i < l->row; i++)
if(!(PRIV(dst)->values[i] = (int *)malloc(r->col * sizeof(int))))
return false;
```
* 發現原本的 code 沒有給 dst->row 跟 dst->col 值,把他加進去
```=vim
dst->row = l->row;
dst->col = r->col;
```
* 問題待解決
* type 只能傳 int
* sse 在 Matrix 的 rows 或 cols 其中一個不是 4 的倍數時無法正常運作
* 參考資料
* [allocate matrix in C](http://stackoverflow.com/questions/2128728/allocate-matrix-in-c)
* [twzjwang 的共筆](https://hackmd.io/s/rkFhTyK3x#)
### 解決 SSE 的 matrix size 限制
* 在 Matrix 的 row 跟 col 不為 4 的倍數時將他 extend 成 4 的倍數,多出來的部份補 0,在最後把 row 跟 col 改成我們要的數字
```=vim
/* extend while not the multiple of 4 */
thiz->row = (row % 4 == 0) ? row : row + (4 - row % 4);
thiz->col = (col % 4 == 0) ? col : col + (4 - col % 4);
```
```
for (i = 0; i < thiz->row; i++) {
for (j = 0; j < thiz->col; j++) {
if (i >= row || j >= col)
PRIV(thiz)->values[i][j] = 0;
```
```
thiz->row = row;
thiz->col = col;
```
* 對 dst 做同樣的 extend
```=vim
/* extend while not the multiple of 4 */
dst->row = (l->row % 4 == 0) ? l->row : l->row + (4 - l->row % 4);
dst->col = (r->col % 4 == 0) ? r->col : r->col + (4 - r->col % 4);
same_line = (l->col % 4 == 0) ? l->col : l->col + (4 - l->col % 4);
```
```
dst->row = l->row;
dst->col = r->col;
```