如無(wú)特別說明邮辽,以下對(duì)應(yīng)問題出現(xiàn)在代碼注釋中千扶。
1. MPI_Send 和 MPI_Recv
這里如果不重新聲明 Recv 的目標(biāo)肆饶,則在 Ubuntu 下無(wú)法正常 Recv 镐躲。
#include "mpi.h"
#include<string.h>
#include<stdio.h>
int main(int argc, char *argv)
{
char message[20];
int myrank;
memset(message, 0, 20);
MPI_Status status;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
if (myrank == 1)
{
printf("randk 0 start ok\n");
strcpy_s(message, 20, "Hello, process 1");
/ 加_s 是因 VS 編譯不通過 /
// strcpy(message, "Hello, process 1");
printf("sended :---%s---\n", message);
MPI_Send(message, strlen(message)+1, MPI_CHAR, 0, 99, MPI_COMM_WORLD);
/ 加 1 是因數(shù)組最后一位是 \0 表示結(jié)束 /
printf("randk 0 finish ok\n");
}
else if (myrank == 0)
{
// char message[20];
/ 這里如果不重新聲明储玫,則在 Ubuntu 下無(wú)法正常 Recv */
printf("randk 1 start ok\n");
MPI_Recv(message, 20, MPI_CHAR, 1, 99, MPI_COMM_WORLD, &status);
printf("received :---%s---\n", message);
printf("randk 1 finish ok\n");
}
MPI_Finalize();
}
2. 時(shí)鐘函數(shù)
參考 MPI程序例子 -- 時(shí)間函數(shù)測(cè)試
(書上莫名其妙調(diào)用不存在的 test.h
真的無(wú)語(yǔ),Windows 里多線程沒問題萤皂,都是 Success撒穷;Linux 中線程為 n 則耗時(shí)為 n 秒,不知什么問題)
#include "mpi.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void sleep(clock_t wait)
/* 如果不重定義敌蚜,則 Windows 里沒有這個(gè)函數(shù)桥滨,Linux 里默認(rèn)是只對(duì)整數(shù)參數(shù)返回非零值 */
{
clock_t goal;
goal = wait + clock();
while (goal > clock())
;
}
int main(int argc, char* argv[]) /* 必要的命令行參數(shù) */
{
int err = 0;
double t1, t2;
double tick;
int i, myrank;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
t1 = MPI_Wtime(); /* 獲得當(dāng)前時(shí)間t1 */
t2 = MPI_Wtime(); /* 獲得當(dāng)前時(shí)間t2 */
if (t2 - t1>0.1 || t2 - t1<0.0)
{
/* 若連續(xù)兩次時(shí)間調(diào)用得到的時(shí)間間隔過大,這里是超過0.1秒弛车,
或者后調(diào)用的函數(shù)得到的時(shí)間比先調(diào)用的時(shí)間小齐媒,則時(shí)間調(diào)用有錯(cuò)。 */
err++;
fprintf(stderr, "Two successive calls to MPI_Wtime gave strange result:(%f)(%f)\n", t1, t2);
}
/* 循環(huán)測(cè)試10次纷跛,每次循環(huán)調(diào)用兩次時(shí)間函數(shù)喻括,兩次時(shí)間調(diào)用的時(shí)間間隔是1秒。 */
for (i = 1; i<10; i++)
{
t1 = MPI_Wtime(); /* 計(jì)時(shí)開始 */
sleep(1000); /* 睡眠1秒 */
//sleep(1000000); /* Linux 微秒單位 */
t2 = MPI_Wtime(); /* 計(jì)時(shí)結(jié)束 */
if (t2 - t1 >= (1.0 - 0.01) && t2 - t1 <= 5.0) break;
if (t2 - t1>5.0) break; /* 兩次計(jì)時(shí)得到時(shí)間間隔合理贫奠,則退出唬血。 */
}
if (i == 10)
{
/* 計(jì)時(shí)函數(shù)不正確 */
fprintf(stderr, "Timer around sleep(1) did not give 1 second;gave %f\n", t2 - t1);
err++;
}
else/* 輸出時(shí)間間隔 */
fprintf(stderr, "Processor %d:Success,t2-t1= %f\n", myrank, t2 - t1);
tick = MPI_Wtick(); /* 得到一個(gè)時(shí)鐘滴答的時(shí)間 */
if (tick>1.0 || tick<0.0)
{
/* 該時(shí)間太長(zhǎng)或者為負(fù)數(shù)望蜡,則該時(shí)間不正確。 */
err++;
fprintf(stderr, "MPI_Wtick gave a strange result: (%f)\n", tick);
}
MPI_Finalize();
return 0;
}
3. Abort 函數(shù)
Linux下沒問題拷恨,輸出結(jié)果隨機(jī)順序脖律。Windows 下 MPI_Abort
會(huì)殺掉所有輸出,而這不是因?yàn)?Windows 反應(yīng)慢(我為了等這個(gè)線程都加了 10 秒富裕時(shí)間)腕侄。
#include "mpi.h"
#include <stdio.h>
#include <string.h>
#include <time.h>
void sleep(clock_t wait)
{
clock_t goal;
goal = wait + clock();
while (goal > clock())
;
}
int main(int argc, char **argv)
{
int node, size, i;
int masternode = 0;
/* 設(shè)置缺省初始值 */
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &node);
MPI_Comm_size(MPI_COMM_WORLD, &size);
/* 檢查參數(shù) */
for (i = 0; i<argc; i++) {
fprintf(stdout, "myid=%d,procs=%d,argv[%d]=%s\n", node, size, i, argv[i]);
}
//if (node == masternode) {
if (node == size - 1) {
/* 由master進(jìn)程執(zhí)行退出操作 */
fprintf(stdout, "myid=%d is masternode Abort!\n", node);
sleep(10000);
MPI_Abort(MPI_COMM_WORLD, 100);
//MPI_Barrier(MPI_COMM_WORLD);
/* MPI_Barrier 就可以得到應(yīng)有的輸出 */
}
else {
/* 非master進(jìn)程等待 */
fprintf(stderr, "myid=%d is not masternode Barrier!\n", node);
MPI_Barrier(MPI_COMM_WORLD);
}
MPI_Finalize();
}
4. 傳值函數(shù)
在 Linux 上直接就通過了小泉,而且結(jié)果正確。在 Windows 上不能輸入冕杠,沒有任何輸出微姊,程序死掉了。
#include <stdio.h>
#include "mpi.h"
int main(int argc, char argv)
{
int rank, value, size;
MPI_Status status;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
do {
if (rank == 0) {
fprintf(stderr, "\nPlease give new value=");
/進(jìn)程0讀入要傳遞的數(shù)據(jù)/
scanf("%d", &value);
fprintf(stderr, "%d read <-<- (%d)\n", rank, value);
if (size>1) {
MPI_Send(&value, 1, MPI_INT, rank + 1, 0, MPI_COMM_WORLD);
fprintf(stderr, "%d send (%d)->-> %d\n",
rank, value, rank + 1);
/* 若不少于一個(gè)進(jìn)程 則向下一個(gè)進(jìn)程傳遞該數(shù)據(jù)/
}
}
else {
MPI_Recv(&value, 1, MPI_INT, rank - 1, 0, MPI_COMM_WORLD,
&status);
/ 其它進(jìn)程從前一個(gè)進(jìn)程接收傳遞過來(lái)的數(shù)據(jù)/
fprintf(stderr, "%d receive (%d)<-<- %d\n", rank, value, rank - 1);
if (rank < size - 1) {
MPI_Send(&value, 1, MPI_INT, rank + 1, 0, MPI_COMM_WORLD);
fprintf(stderr, "%d send (%d)->-> %d\n",
rank, value, rank + 1);
/若當(dāng)前進(jìn)程不是最后一個(gè)進(jìn)程 則將該數(shù)據(jù)繼續(xù)向后傳遞/
}
}
MPI_Barrier(MPI_COMM_WORLD);
/ 執(zhí)行一下同步 加入它主要是為了將前后兩次數(shù)據(jù)傳遞分開/
} while (value >= 0);
/ 循環(huán)執(zhí)行 直到輸入的數(shù)據(jù)為負(fù)時(shí)才退出 */
MPI_Finalize();
}
5. 互相問候
#include "mpi.h"
#include <stdio.h>
#include <stdlib.h>
void Hello(void);
int main(int argc, char *argv[])
{
int me, option, namelen, size;
char processor_name[MPI_MAX_PROCESSOR_NAME];
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &me);
MPI_Comm_size(MPI_COMM_WORLD, &size);
/*得到當(dāng)前進(jìn)程標(biāo)識(shí)和總的進(jìn)程數(shù)*/
if (size < 2) {
/*若總進(jìn)程數(shù)小于2 則出錯(cuò)退出*/
fprintf(stderr, "systest requires at least 2 processes");
MPI_Abort(MPI_COMM_WORLD, 1);
}
MPI_Get_processor_name(processor_name, &namelen);
/*得到當(dāng)前機(jī)器名字*/
fprintf(stderr, "Process %d is alive on %s\n", me, processor_name);
MPI_Barrier(MPI_COMM_WORLD);
/*同步*/
Hello();
/*調(diào)用問候過程*/
MPI_Finalize();
}
void Hello(void)
/*任意兩個(gè)進(jìn)程間交換問候信息 問候信息由發(fā)送進(jìn)程標(biāo)識(shí)和接收進(jìn)程標(biāo)識(shí)組成*/
{
int nproc, me;
int type = 1;
int buffer[2], node;
MPI_Status status;
MPI_Comm_rank(MPI_COMM_WORLD, &me);
MPI_Comm_size(MPI_COMM_WORLD, &nproc);
/*得到當(dāng)前進(jìn)程標(biāo)識(shí)和總的進(jìn)程數(shù)*/
if (me == 0) {
/* 進(jìn)程0負(fù)責(zé)打印提示信息*/
printf("\nHello test from all to all\n");
fflush(stdout);
}
for (node = 0; node<nproc; node++) {
/*循環(huán)對(duì)每一個(gè)進(jìn)程進(jìn)行問候*/
if (node != me) {
/* 得到一個(gè)和自身不同的進(jìn)程標(biāo)識(shí)*/
buffer[0] = me; /*將自身標(biāo)識(shí)放入消息中*/
buffer[1] = node; /*將被問候的進(jìn)程標(biāo)識(shí)也放入消息中*/
MPI_Send(buffer, 2, MPI_INT, node, type, MPI_COMM_WORLD);
/*首先將問候消息發(fā)出 */
MPI_Recv(buffer, 2, MPI_INT, node, type, MPI_COMM_WORLD, &status);
/*然后接收被問候進(jìn)程對(duì)自己發(fā)送的問候消息*/
if ((buffer[0] != node) || (buffer[1] != me)) {
/*若接收到的消息的內(nèi)容不是問候自己的或不是以被問候方的身份問候自
己 則出錯(cuò)*/
(void)fprintf(stderr, "Hello: %d!=%d or %d!=%d\n",
buffer[0], node, buffer[1], me);
printf("Mismatch on hello process ids; node = %d\n", node);
}
printf("Hello from %d to %d\n", me, node);
/*打印出問候?qū)Ψ匠晒Φ男畔?/
fflush(stdout);
}
}
}