# 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; ```