完數的MPI並行程式設計-平行計算
目錄
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 MPI訊息傳遞並行演算法設計
並行演算法步驟如下:
①初始化MPI執行環境,程式號為零時輸入n,隨後將 n 值廣播出去;②中間計算步驟與序列計算步驟相同;
③暫存各個程式平行計算得到的部分和,通過MPI_SUM函式來彙總資料,各個程式全部執行完畢即得最終計算答案。
2.3 理論加速比分析
若p個處理器上資料量為n,則S=np/(n+2plogp)。
本機測試中,p=2:若n=10000,則S=1.99976;若n=100000,則S=1.99998。
3.基於MPI的並行演算法實現
3.1 程式碼及註釋(變數名 名字首字母 開頭)
/*問題描述:一個數如果恰好等於它的因子之和,這個數就稱為“完數”。例如6=1+2+3,再如8的因子和是7(即1+2+4),8不是完數。程式設計找出1000以內的所有完數。
*/
//test.cpp : 定義控制檯應用程式的入口點。
//
#include "stdafx.h"
#include "mpi.h"
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <ctime>
#include <omp.h>
#include <windows.h>
using namespacestd;
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;
printf("%lld\n", sum);
} //函式返回答案值ans
}
return ans;
}
int main(int argc, char *argv[])
{
long long n,temp;
long long i,k; //迴圈變數
int done = 0, myid, numprocs;
long longmypi, pi, ans;// n以內的完數個數
double startwtime, endwtime;
int namelen;
charprocessor_name[MPI_MAX_PROCESSOR_NAME];
MPI_Init(&argc,&argv);//初始化
MPI_Comm_size(MPI_COMM_WORLD,&numprocs);//標示相應程式組中有多少個程式
printf("numprocs= %d\n", numprocs);
MPI_Comm_rank(MPI_COMM_WORLD, &myid);//標示各個MPI程式,告訴呼叫該函式程式的當前程式號
MPI_Get_processor_name(processor_name,&namelen);//獲取當前程式執行的機器名稱
fprintf(stderr, "Process %d on %s\n", myid, processor_name);
fflush(stderr);
while (!done)
{
if(myid == 0)
{
printf("輸入一個數字不超過: (0 退出) ");
fflush(stdout);
scanf_s("%lld",&n);
temp = n;
startwtime = MPI_Wtime();
printf("%lld以內的完數有:\n",n);
}
/***************MPI平行計算n以內的完數個數*********************/
MPI_Bcast(&n, 1, MPI_LONG, 0,MPI_COMM_WORLD);//將 n 值廣播出去
if (n== 0) done = 1;
else
{
ans = 0;
for (i= myid + 2; i <= n; i += numprocs) //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
printf("%lld\n", sum);
}
}
mypi = ans;//各個程式平行計算得到的部分和
MPI_Reduce(&mypi, &pi, 1,MPI_LONG, MPI_SUM, 0, MPI_COMM_WORLD);//每個程式從sendBuf向root程式的receiveBuf發資料,通過opration函式(例如MPI_SUM)來彙總資料
if(myid == 0)
{
//執行累加的號程式將近似值列印出來
printf("Sum= %d\n", pi);
endwtime = MPI_Wtime();//返回自過去某一時刻呼叫時的時間間隔,以秒為單位
printf("MPI時間= %f\n",endwtime - startwtime);
/*****************序列計算時間***********************/
startwtime = MPI_Wtime();
printf("Sum= %d\n", Perfect(temp)); //輸出序列計算出的n以內的完數個數
endwtime = MPI_Wtime();
printf("Serail時間= %f\n",endwtime - startwtime);//輸出序列計算時間
/****************************************/
}
}
}
MPI_Finalize();
system("pause");
return 0;
}
3.2 單機執行
3.2.1 執行結果截圖
(1)小資料量驗證正確性的執行結果截圖(不考慮加速比)
(2)大資料量獲得較好加速比的執行結果截圖
(體現序列時間、並行時間和好的加速比)
3.2.2 實驗加速比分析
若n=10000,S=Ts/Tp=2.0045;若n=100000,S=Ts/Tp=1.9976。
實驗加速比與理論加速比相差不大,在誤差允許範圍內可認為結果正確。
3.3 多機執行
3.3.1 程式執行說明
使用Dell20201與Dell20202兩臺機器組成雙核執行平臺,程式分配如圖所示。
3.3.2 執行結果截圖
(1)小資料量驗證正確性的執行結果截圖(不考慮加速比)
(2)大資料量獲得較好加速比的執行結果截圖
(體現序列時間、並行時間和好的加速比)
3.3.3 實驗加速比分析
若n=10000,S=Ts/Tp=2.0027;若n=100000,S=Ts/Tp=2.000484。
實驗加速比與理論加速比相差不大,在誤差允許範圍內可認為結果正確。
3.4 遇到的問題及解決方案
3.4.1錯誤程式碼
long long ans;
double mypi, pi;
(此處略中間程式碼)
mypi =ans;//各個程式平行計算得到的部分和
MPI_Reduce(&mypi,&pi, 1, MPI_LONG, MPI_SUM, 0, MPI_COMM_WORLD);
3.4.2後果
通過MPI_SUM函式來彙總的資料pi錯誤,輸出為零。
3.4.3正確程式碼
long long mypi, pi, ans;//ans是n以內的完數個數
(此處略中間程式碼)
mypi =ans;//各個程式平行計算得到的部分和
MPI_Reduce(&mypi,&pi, 1, MPI_LONG, MPI_SUM, 0, MPI_COMM_WORLD);
3.4.4分析
相互賦值的兩個變數的資料型別必須相同,不然無法完成賦值,始終為預設值零。
相關文章
- 完數的OpenMP並行程式設計-平行計算並行行程程式設計
- 完數的Java多執行緒並行程式設計-平行計算Java執行緒並行行程程式設計
- OpenMP平行計算程式設計-n以內的完數的個數程式設計
- 大資料平行計算利器之MPI/OpenMP大資料
- 平行計算與並行程式設計課程內容介紹並行行程程式設計
- .NET並行程式設計實踐(一:.NET平行計算基本介紹、並行迴圈使用模式)並行行程程式設計模式
- cuda程式設計與gpu平行計算(四):cuda程式設計模型程式設計GPU模型
- 基於MPI的文件分類並行程式設計(C)並行行程程式設計
- 世界是並行的:平行計算的機遇與挑戰並行
- MPI矩陣向量乘法程式碼《並行程式設計導論》矩陣並行行程程式設計
- 淺談.NET下的多執行緒和平行計算(十四)平行計算前言執行緒
- 平行計算π值
- Oracle平行計算Oracle
- 平行計算cuda
- OpenCV使用ParallelLoopBody進行平行計算OpenCVParallelOOP
- [原始碼解析] PyTorch 流水線並行實現 (6)--平行計算原始碼PyTorch並行
- GPU:平行計算利器GPU
- cuda程式設計與gpu平行計算(六):圖稀疏矩陣轉為CSR結構並傳入gpu程式設計GPU矩陣
- Linux虛擬機器中配置多節點MPI實現平行計算完整版Linux虛擬機
- 推薦文章:多執行緒平行計算執行緒
- 後端請求中的非同步計算與平行計算後端非同步
- 雲端計算分散式平行計算:系統架構分散式架構
- 瞭解Flow -- elixir的平行計算庫
- 引文——平行計算的學習之殤
- 多核平行計算時代的來臨
- 在手機上程式設計:自制的小飛可程式設計複數計算器(小飛計算器)程式設計
- 使用 QuTrunk+Amazon ParallelCluster3 進行平行計算Parallel
- .NET4.0平行計算技術基礎(2)
- .NET4.0平行計算技術基礎(1)
- Python多核程式設計mpi4py實踐Python程式設計
- Java中的函數語言程式設計(八)流Stream並行程式設計Java函數程式設計並行行程
- 大文字平行計算實現方式
- 黃仁勳:序列計算過時平行計算是未來
- JDK7的平行計算功能升級JDK
- (Python程式設計 | 系統程式設計 | 並行系統工具 | 程式退出)Python程式設計並行
- Java執行緒(十一):Fork/Join-Java平行計算框架Java執行緒框架
- 學完程式設計你能從事哪些行業?程式設計行業
- Shell程式設計-04-Shell中變數數值計算程式設計變數