作為例子問題是1000
×1000
1000 \times 1000
1000×1
000的矩陣和向量相乘。使用了4個執行緒。
先打一下預防針。矩陣乘向量這個問題太簡單了,一定要使用foster設計方法反而覺得foster有些累贅。例如資訊傳遞、整合實際上完全可以沒有操作,直接在劃分的時候就一次性解決。但是,在後來解決n-body等問題的時候foster設計方法才能更好的展現它的作用。
2.1 partitioning
首先將問題劃分為更細小的子任務。
在向量乘矩陣的大問題下可以把問題分解為106
10^6
106次乘法和若干次加法。乘法的運算量遠高於加法,因此只把乘法當作最小的子任務。
2.2.2 communication
在資訊傳遞的設計階段,要考慮各個執行緒之間要傳遞的資料或者要用共享變數傳遞的資料。
之前劃分過程得到的各個乘法子任務的計算結果要交給乙個執行緒求和。
很明顯這樣的資訊傳遞的過程比較繁瑣,花費的代價也比較高,在下乙個整合步驟會解決這個問題。
2.2.3 agglomeration
整合步驟是將之前劃分得到的子問題合併,目的是減少資訊傳遞的代價或減少程式設計量。
在整合時可以將一行矩陣和向量的乘法合併為乙個子問題,這樣就完全消除了資訊傳遞的代價。而且只要矩陣維度可以被執行緒數整除那麼每個執行緒解決的問題量就是一樣的。
實際上,正常思路都是就將計算一行乘法劃分為乙個子任務。這裡只是為了突出foster設計思路才將每一次乘法劃分開。
對映的過程是將執行緒(子問題)對映到處理器的過程。這個過程直接由作業系統或者硬體控制,程式設計師一般情況下不會通過**控制。
下表給出了foster設計方法在每一步的設計
步驟名稱
設計partitioning
將矩陣元素和向量元素每一次乘法劃分為乙個子問題
communication
每次乘法的計算結果要彙總
agglomeration
將一行的乘法合併成乙個任務
將執行緒分給不同的處理單元
附錄:**實現
#include
#include
#include
#define dimension 12
int*
*matrix;
int*vec;
int*result;
int thread =4;
void
*mul
(void
*r);
intmain()
printf
("before mul vec:\n");
for(i =
0; i < dimension;
++i)
printf
("%d "
, vec[i]);
printf
("\n");
pthread_t *handles =
(pthread_t *
)malloc
(thread *
sizeof
(pthread_t));
for(i =
0; i < thread;
++i)
pthread_create
(&handles[i]
,null
, mul,\
(void
*)i)
;for
(i =
0; i < thread;
++i)
pthread_join
(handles[i]
,null);
printf
("after mul vec:\n");
for(i =
0; i < dimension;
++i)
printf
("%d "
, result[i]);
printf
("\n");
free
(handles)
;free
(vec)
;free
(result)
;for
(i =
0; i < dimension;
++i)
free
(matrix[i]);
free
(matrix)
;return0;
}void
*mul
(void
*r)
rowKey設計原則 設計方法
1 rowkey 長度原則 rowkey是乙個二進位製碼流,可以為任意字串,最大長度為64kb,實際應用中一般為10 100bytes,它以byte形式儲存,一般設定成定長。一般越短越好,不要超過16個位元組,注意原因如下 1 目前作業系統都是64位系統,記憶體8位元組對齊,控制在16位元組,8位元...
演算法設計方法
演算法設計有很多方法,以下是我蒐集的一些資料如 1 蠻力法 蠻力法 brute force method 也稱為窮舉法,是一種簡而直接地解決問題的方法。所依賴的基本技術是掃瞄技術 即採用一定的策略將待求解的問題的所有元素依次處理一次,從而找出問題的解。依次處理所有元素是蠻力法的關鍵,為了避免陷入重複...
django RESTful設計方法
應該盡量將api部署在專用網域名稱之下。如果確定api很簡單,不會有進一步擴充套件,可以考慮放在主網域名稱下。應該將api的版本號放入url。另一種做法是,將版本號放在http頭資訊中,但不如放入url方便和直觀。github採用這種做法。因為不同的版本,可以理解成同一種資源的不同表現形式,所以應該...