contents
題目描述
給予序列 $A \left[ 1 \cdots n \right]$,請計算前綴和序列 $S \left[ 1 \cdots n \right]$,其中 $$S \left[ i \right] = \sum_{k=1}^{i} A \left[ k \right]$$
為了檢測方便,移除輸入和輸出時間,序列 $A$ 由一個簡單加密 $\textit{key}$ 得到序列 $$A \left[ i \right] = \textit{encrypt}(i, \textit{key})$$以及輸出部分直接呼叫$\textit{output}(\textit{S}, n)$。注意$S\left[ 0 \right] = 0$,儲存答案的範圍為$S\left[ 1 \cdots n \right]$。
utils.h
可以直接 #include "utils.h"
在你的程式中。
|
|
prefixsum-seq.c
請修改這份程序。
|
|
secret.c (測試用)
實際情況會用助教寫好的平行方式進行計算且雜湊公式不同。
|
|
輸入格式
輸入有多組測資,每組測資一行兩個整數 $n$, $\textit{key}$,分別為序列長度 $n$,加密金鑰 $\textit{key}$。
- $1 \le n \le 10^7$
- $0 \le key < 2^{32}$
輸出格式
對於每一組測資呼叫 output(uint32_t presum[], int n)
,隨後會輸出一個數值。
範例輸入
|
|
範例輸出
|
|
範例解釋
- $(n, \textit{key})=(3, 2)$,得 $A \left[ 1 \cdots 3\right] = \left[ 4, 8, 12 \right]$,$S \left[ 1 \cdots 3\right] = \left[ 4, 12, 24 \right]$,$\text{hash} = 4 + 12 \times 2 + 24 \times 3 = 100$
編譯方式
|
|
測試主機資訊
推薦使用 4 個執行緒解決此問題,平行效能接近 2 倍改進。若使用過多的執行緒,將因為要排到另一個處理器上運行而變慢。
|
|
Solution
利用 $P$ 的 thread,分開計算區間 $[1, N/P], \; [N/P+1, 2N/P], \cdots$ 的前綴和,由於前綴和只有利用加法計算,加法具有結合律,隨後傳遞前 $i$ 段的和,可以循序 $\mathcal{O}(P)$ 完成,或者利用樹形平行 (tree-based) 的方式在 $\mathcal{O}(\log P)$,在實務上直接循序即可。
由於採用分治方式,需要平行兩次,時間複雜度為 $\mathcal{O}(2 \frac{N}{P} + P)$。
- 當 $P = 3$ 時,只獲得 1.5 倍的加速
- 當 $P = 4$ 時,獲得 2 倍加速
- 當 $P > 4$ 時,要將記憶體的部分傳到另一顆 CPU 上,假設搬運時間是線性正比,計算複雜度也是線性時間,那麼搬運時間不如在同一顆 CPU 上運行。
|
|