使用MPI並行求解字首和 prefix sum

2021-07-07 01:35:21 字數 1529 閱讀 3203

本文介紹的並行模式是字首和(prefixsum),通常也叫掃瞄(scan)。從數學的角度看,閉掃瞄(inclusive scan)操作接受乙個二元運算子和乙個n元輸入陣列[x0,x1,…,xn-1],然後返回乙個輸出陣列:

[x0,(x0+x1),…,(x0+x1  … +xn-1)]。

在介紹並行掃瞄演算法與它們的實現前,先介紹乙個高效的序列閉掃瞄演算法以及它的實現。

void sequential_scan(int *x, int *y, int size)

}

這個是演算法的效率很高,每處理乙個輸入元素x,計算機只需要做一次加法、一次儲存器載入和一側儲存器儲存。

本文介紹乙個簡單的並行掃瞄演算法,該演算法對所有輸出元素進行歸約操作,它的核心思想是通過為每個輸出元素計算相關輸入元素的歸約樹來快速建立每個元素。

這是乙個原地掃瞄演算法,它對輸入陣列xy進行操作。開始的時候xy陣列中儲存的是輸入元素,然後演算法迭代地把陣列中的內容轉化為輸出元素。

上圖每一豎行代表xy陣列的乙個元素,xy[0]在最左邊,豎直方向表示迭代的過程。在演算法開始前,假設xy[i]中儲存了輸入元素xi,在n次迭代以後,xy[i]中儲存的是這個位置之前(包括這個位置)2^n個輸入元素之和,即在第1次迭代結束後,xy[i]中儲存的是xi-1 + xi,在第2次迭代結束後,xy[i]中儲存的是

xi-3 + xi-2 + xi-1 + xi,以此類推。

// parallel prefix sum

#include #include #include #include int main()

if (my_rank > cutidx || my_rank == cutidx)

cutidx *= 2;

step *= 2;

} if (my_rank != 0)

else

for (j = 0; j < pno; j++)

printf("\n");

free(outputarray);

} mpi_finalize();

return 0;

}

所有程序將迭代log2(n)步,其中n等於程序數目。每次迭代中,不需要做加法的執行緒的數量等於跨步大小,計算演算法完成的工作量:

∑(n- step), for step 1,2,4,…,n/2  (log2(n)項)

每一項的第乙個部分和跨步無關,和是n * log2(n),第二部分類似等比級數,它們的和為n-1。所以加法操作的總數是:

n * log2(n) – (n - 1)

注意序列演算法完成的加法總數為n-1。計算同樣資料量的字首和,這種簡單並行演算法需要幾倍的執行單元才能達到和序列**一樣的速度。額外的執行資源和並行中額外開銷使得該演算法效率不高。

為了提高效率,可以共享一些中間結果,如利用歸約樹得到的「子和」,來計算掃瞄的其他輸出值。

MPI並行求向量和

教材是 並行程式設計導論 參考該教材。用了mpi scatter和mpi gather allgather也一樣,不寫destination的引數就行了 中注釋掉的部分是測試時從命令列輸入向量使用的,那個時候把n設了12。因為要求是n 10000,所以我直接讓第i個元素等於i,並且只輸出了i 112...

藍橋杯 k倍區間(利用字首和求解

時間限制 1sec 記憶體限制 128mb 題目描述給定乙個長度為n的數列,a1,a2,an,如果其中一段連續的子串行ai,ai 1,aj i j 之和是k的倍數,我們就稱這個區間 i,j 是k倍區間。列中總共有多少個k倍區間嗎?輸入 第一行包含兩個整數n和k。1 n,k 100000 以下n行每行...

python mpi 安裝和使用 mpi4py

安裝依賴 要正確地安裝和使用 mpi4py,你需要先安裝和設定好以下軟體 乙個 mpi 實現軟體,最好能支援 mpi 3 標準,並且最好是動態編譯的。比較常用的 mpi 實現軟體有 openmpi,mpich 等。python 2.7,python 3.3 要寫 python 的並行程式,pytho...