contents
背景
題目描述
相信不少人都已經實作所謂的矩陣乘法,計算兩個方陣大小為 $N \times N$ 的矩陣 $A, B$。為了方便起見,提供一個偽隨機數的生成,減少在輸入處理浪費的時間,同時也減少上傳測資的辛苦。
根據種子 $c = S1$ 生成矩陣 $A$,種子 $c = S2$ 生成矩陣 $B$,計算矩陣相乘 $A \times B$,為了方便起見,使用 hash 函數進行簽章,最後輸出一個值。由於會牽涉到 overflow 問題,此題作為快取實驗就不考慮這個,overflow 問題都會相同。
matrix.h
|
|
matrix.c
|
|
main.c
|
|
輸入格式
多組測資,每組測資一行三個整數 $N, S1, S2$。
- $1 \le N \le 1000$
- $0 \le S1, S2 \le 65536$
輸出格式
每組測資輸出一行,一個整數 signature 的結果。
範例輸入
|
|
範例輸出
|
|
解釋
範例輸入產生 $2 \times 2$ 的矩陣。
$$A = \begin{bmatrix} 2 & 3\\ 0 & 0 \end{bmatrix} , B = \begin{bmatrix} 1 & 3\\ 3 & 0 \end{bmatrix} , A \times B = \begin{bmatrix} 11 & 6\\ 0 & 0 \end{bmatrix}$$備註
- 2016/02/17 加入平行程式設計 OpenMP 部份,並增加時間限制!
Solution
解法跟 thread 寫法一樣,用 OpenMP 的好處在於不用處理那些 thread 的設定,用 OpenMP 提供的前處理完成執行緒的建造和移除操作。
在這裡特別提供達夫裝置 (Duff’s device) 對於迴圈展開 loop unrolling 的撰寫方式,巧妙地運用 C 語言中的 switch,相比一般寫法需要兩次迴圈處理,最後一個迴圈必須處理剩餘不整除的部分。就實作看起來,在現在版本 4.8 gcc 編譯結果下,效能沒有明顯的差別。
在高等編譯器課程中,聽說迴圈展開的數目最好不是 $2^n$,某些情況會造成 alignment 的 cache miss 的嚴重影響,實際情況還是要看怎麼運用,在這裡就不多做嘗試。
matrix.h
|
|
matrix.c (達夫裝置)
|
|
matrix.c (迴圈展開)
|
|