Try   HackMD

2017q1 Homework5 (matrix)

contributed by <Weinux>

tags: sysprog2017 w5 matrix Weinux

相關連結

開發環境

  • 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® Core i5-2410M CPU @ 2.30GHz
  • Model name: Intel® Core 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.
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 版本的實作

MatrixAlgo NaiveMatrixProvider = { .assign = assign, .equal = equal, .mul = mul, };
  • 因此在主要測試程式 test-matrix.c 中, 有一個 MatrixAlgo* 陣列 matrix_providers[] 未來實作 AVX SSE 版本時, 只需要在陣列中加入其他的 provider 就可以在 main 切換不同實作

一開始的版本

#include "matrix.h" #include <stdio.h> MatrixAlgo *matrix_providers[] = { &NaiveMatrixProvider, }; int main() { MatrixAlgo *algo = matrix_providers[0];

未來可能的版本

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