完數的OpenMP並行程式設計-平行計算
目錄
1.問題描述
一個數如果恰好等於它的因子之和,這個數就稱為“完數”。例如6=1+2+3,再如8的因子和是7(即1+2+4),8不是完數。輸入一個數n,程式設計找出n以內的所有完數及其個數。
2.演算法設計
2.1 序列演算法設計
序列演算法步驟如下
①因為1不算入一個完數,所以令數i=2,初始化答案值ans=0;
②因為1是任何數的一個因數,所以可初始化因數之和sum=1;
③令數k=2;
④如果數i能整除數k,說明k是i的一個因數,則sum += k;
⑤若k<=i/2(控制範圍保證i%k能進行計算),++k,轉到④,否則轉到⑥;
⑥若sum = i,++ans;
⑦若i <=n,++i,轉到②,否則轉到⑧;
⑧函式返回答案值ans。
2.2 並行演算法設計
並行演算法步驟如下
①因為1不算入一個完數,所以令數i=2,初始化答案值ans=0;
②“#pragmaomp parallel for”
②因為1是任何數的一個因數,所以可初始化因數之和sum=1;
“#pragmaomp parallel for”
③令數k=2;
“#pragmaomp critical”
④如果數i能整除數k,說明k是i的一個因數,則sum += k;
⑤若k<=i/2(控制範圍保證i%k能進行計算),++k,轉到④,否則轉到⑥;
⑥若sum = i,++ans;
⑦若i <=n,++i,轉到②,否則轉到⑧;
⑧函式返回答案值ans。
2.3 理論加速比分析
若p個處理器上資料量為n,則S=np/(n+2plogp)。
本機測試中,p=4:若n=10000,則S=3.9981;若n=100000,則S=3.9998。
3.基於OpenMP的並行演算法實現
3.1 程式碼及註釋(變數名 名字首字母 開頭)
/*問題描述:一個數如果恰好等於它的因子之和,這個數就稱為“完數”。例如6=1+2+3,再如8的因子和是7(即1+2+4),8不是完數。程式設計找出1000以內的所有完數。
*/
//test.cpp : 定義控制檯應用程式的入口點。
//
#include "stdafx.h"
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <ctime>
#include <omp.h>
#include <windows.h>
using namespace std;
int OMP_Perfect(long long n) //平行計算n以內的完數個數
{
int ans = 0; // n以內的完數個數
long long i, k; //迴圈變數
#pragma omp parallel for
for (i = 2; i <= n;i++) //1不算入一個完數。
{
long long sum = 1; //數的因數之和,1是任何數的一個因數。
#pragma omp parallel for reduction(+:sum) //解決sum資料衝突
for (k = 2; k <= i / 2; k++) //k<=i/2是要保證i%k能進行計算。
if(i%k == 0)
sum += k; //因數之和
if (sum == i) //找到一個完數
++ans; //函式返回答案值ans
}
return ans;
}
int Perfect(long long n)
{
int ans = 0; // n以內的完數個數
long long i, k; //迴圈變數
for (i = 2; i <= n;i++) //1不算入一個完數。
{
long long sum = 1; //數的因數之和,1是任何數的一個因數。
for (k = 2; k <= i / 2; k++) //k<=i/2是要保證i%k能進行計算。
if(i%k == 0)
sum += k; //因數之和
if (sum == i) //找到一個完數
++ans; //函式返回答案值ans
}
return ans;
}
int main()
{
long long n;
cin >> n;
printf("%lld以內的完數有:\n",n);
clock_t t1, t2;
t1 = clock();
printf("Sum= %d\n", OMP_Perfect(n)); //輸出平行計算出的n以內的完數個數
t2 = clock();
printf("parallel time: %d\n", t2 - t1);//輸出平行計算時間
t1 = clock();
printf("Sum= %d\n", Perfect(n)); //輸出序列計算出的n以內的完數個數
t2 = clock();
printf("serail time: %d\n", t2 - t1); //輸出序列計算時間
system("pause");
return 0;
}
3.2 執行結果截圖
(1)小資料量驗證正確性的執行結果截圖(不考慮加速比)
(2)大資料量獲得較好加速比的執行結果截圖
(體現序列時間、並行時間 和好的加速比)
3.3 實驗加速比分析
若n=10000,S=Ts/Tp=3.7857;若n=100000,S=Ts/Tp=3.7420。
實驗加速比與理論加速比相差不大,在誤差允許範圍內可認為結果正確。
3.4 遇到的問題及解決方案
3.4.1錯誤程式碼
int OMP_Perfect(longlong n)
{
int ans = 0;
long long i, k;
#pragma omp parallel for
for (i = 2; i <= n;i++)
{
long long sum = 1;
#pragma omp parallel for
for (k = 2; k <= i / 2; k++)
if(i%k == 0)
sum += k;
if (sum == i) ++ans;
}
return ans;
}
3.4.2後果
n以內的完數數量答案錯誤。
3.4.3正確程式碼
int OMP_Perfect(longlong n) //平行計算n以內的完數個數
{
int ans = 0; // n以內的完數個數
long long i, k; //迴圈變數
#pragma omp parallel for
for (i = 2; i <= n;i++) //1不算入一個完數。
{
long long sum = 1; //數的因數之和,1是任何數的一個因數。
#pragma omp parallel for reduction(+:sum) //解決sum資料衝突
for (k = 2; k <= i / 2; k++) //k<=i/2是要保證i%k能進行計算。
if(i%k == 0)
sum += k; //因數之和
if (sum == i) //找到一個完數
++ans; //函式返回答案值ans
}
return ans;
}
3.4.4分析
由於是多執行緒執行,有超過兩個執行緒同時訪問一個記憶體區域,並且至少有一個執行緒的操作是寫操作,這樣就產生了資料競爭。如果不對資料競爭進行處理,結果會產生錯誤。
第二個for語句並行使用“#pragma ompparallel for reduction(+:sum)”來解決sum的資料競爭問題。因為reduction子句為變數指定一個操作符,每個執行緒都會建立reduction變數的私有副本,在OpenMP區域結束處,將使用各個執行緒私有複製的值通過制定的操作符進行迭代運算,並賦值給原來的變數。
相關文章
- 平行計算與並行程式設計課程內容介紹並行行程程式設計
- cuda程式設計與gpu平行計算(四):cuda程式設計模型程式設計GPU模型
- java8平行計算Java
- [原始碼解析] PyTorch 流水線並行實現 (6)--平行計算原始碼PyTorch並行
- 平行計算π值
- OpenCV使用ParallelLoopBody進行平行計算OpenCVParallelOOP
- 高效能運算-openmp程式設計-深入理解(for-collapse)程式設計
- springboot~CompletableFuture平行計算Spring Boot
- cuda程式設計與gpu平行計算(六):圖稀疏矩陣轉為CSR結構並傳入gpu程式設計GPU矩陣
- 後端請求中的非同步計算與平行計算後端非同步
- 平行計算與Neon簡介
- (Python程式設計 | 系統程式設計 | 並行系統工具 | 程式退出)Python程式設計並行
- 瞭解Flow -- elixir的平行計算庫
- 使用 QuTrunk+Amazon ParallelCluster3 進行平行計算Parallel
- Java中的函數語言程式設計(八)流Stream並行程式設計Java函數程式設計並行行程
- OpenMP 原子指令設計與實現
- 大文字平行計算實現方式
- 學完程式設計你能從事哪些行業?程式設計行業
- 並行程式設計並行行程程式設計
- Shell程式設計-04-Shell中變數數值計算程式設計變數
- .NET併發程式設計-資料並行程式設計並行
- 程式設計師的計算機配置程式設計師計算機
- [python] Python平行計算庫Joblib使用指北Python
- 【1】Embarrassingly Parallel(易平行計算問題)Parallel
- [930]python平行計算框架pathos模組Python框架
- Python並行程式設計Python並行行程程式設計
- GPU程式設計(四):並行規約優化GPU程式設計並行優化
- 併發程式設計-6.並行程式設計概念程式設計並行行程
- 併發程式設計-8.並行資料結構和並行Linq程式設計並行資料結構
- 兩行程式碼輕鬆讓 Java 實現大文字平行計算行程Java
- 簡單幾行程式碼輕鬆實現大文字平行計算行程
- C#並行,多執行緒程式設計並行集合和PLINQ的例項講解並行執行緒程式設計
- mapreduce的程式設計模型,計數器程式設計模型
- HPC高效能運算知識: 異構平行計算
- Python 並不合適職場程式設計,SPL 才行Python程式設計
- .NET併發程式設計-任務函式並行程式設計函式並行
- 計算機程式設計心得總結計算機程式設計
- 10 早期計算機如何程式設計計算機程式設計
- 2024 計算導論與程式設計程式設計