-
目录
第 1 章 – 简介
1.1 – 概述
1.2 – 兼容性
第 2 章 – 安装英特尔® MPI 库
2.1 – 安装英特尔 MPI 库
2.2 – 准备
第 3 章 – 编译和运行示例 MPI 程序
附录
作者简介
第1章 简介
本文旨在帮助用户在包括英特尔® 至强 融核™ 协处理器的开发平台上开始编写代码并运行消息传递接口 (MPI) 应用(使用英特尔® MPI 库)。
更具体地说,本白皮书中使用的英特尔® MPI 库是面向 Linux* 操作系统的英特尔 MPI 库 4.1。该英特尔 MPI 库同时支持英特尔® 至强® 处理器和英特尔® 至强 融核™ 协处理器。
1.1 – 概述
面向 Linux 操作系统的英特尔 MPI 库是一种基于 ANL* MPICH2* (http://www.mcs.anl.gov/research/projects/mpich2/ ) 和 OSU* MVAPICH2* (http://mvapich.cse.ohio-state.edu/download/mvapich2/ ) 的多结构消息传递库。
面向 Linux 操作系统的英特尔 MPI 库实施消息传递接口, 2.2 版 (MPI-2.2) 规范。
它目前支持面向 Linux 操作系统 12.1 版及更高版本的英特尔® C++ 编译器和英特尔® Fortran 编译器。用户可以在 C、C++、Fortran 77 和 Fortran 90 中编写其代码。
1.2 – 兼容性
面向 Linux 操作系统的英特尔 MPI 库支持大量不同的操作系统,其中包括:
Red Hat* Enterprise Linux 64-bit 6.0 内核 2.6.32-71
Red Hat Enterprise Linux 64-bit 6.1 内核 2.6.32-131
Red Hat Enterprise Linux 64-bit 6.2 内核 2.6.32-220
Red Hat Enterprise Linux 64-bit 6.3 内核 2.6.32-279
SUSE* Linux Enterprise Server 11 SP1 内核 2.6.32.12-0.7-默认
SUSE Linux Enterprise Server 11 SP2 内核 3.0.13-0.27-默认
根据在上述平台上运行的英特尔® 众核平台系统软件 (MPSS) 的不同,您需要使用正确的编译器(面向 Linux 操作系统的英特尔® Composer XE 2013)。
请注意,面向 Linux 操作系统的英特尔 MPI 库 4.1 支持多种英特尔® 至强 融核™ 协处理器。
本文的第一部分介绍了如何在 MPSS 2.1 上安装英特尔 MPI 库 4.1。第二部分介绍了如何在英特尔® 至强 融核™ 协处理器上运行某些 MPI 示例代码。
第2章 安装英特尔MPI库
2.1 – 安装英特尔 MPI 库
安装英特尔 MPI 库之前,您必须按照相应的步骤安装最新版本的英特尔 C/C++ 编译器和英特尔 Fortran 编译器。本文中使用的版本为 2013。
您可以通过 http://software.intel.com/en-us/linux-tool-suites 购买这些软件开发工具。这些说明假设您获得这些工具后具备英特尔 MPI 库 tar 文件 l_mpi_p_4.1.0.024.tgz。
解包 tar 文件 l_mpi_p_4.1.0.024.tgz:
# tar -xzvf l_mpi_p_4.1.0.024.tgz
# cd l_mpi_p_4.1.0.024
# ls
cd_eject.sh
INSTALL.html
install.sh
license.txt
pset
Release_Notes.txt
rpm
SilentInstallConfigFile.ini
sshconnectivity.exp
运行 install.sh 脚本并按照说明操作。对于特定用户,安装程序位于安装目录 installation directory $HOME/intel/impi/4.1.0.024 中。对于根用户来说,软件安装在 /opt/intel/impi/4.1.0.024 目录中(假设您使用根权限执行安装)。
# sudo ./install.sh
# ls -l /opt/intel/impi/4.1.0.024
total 208
-rw-r--r-- 1 root root 28556 Aug 31 07:48 Doc_Index.html
-rw-r--r-- 1 root root 9398 Aug 31 07:48 README.txt
lrwxrwxrwx 1 root root 8 Sep 22 17:07 bin -> ia32/bin
lrwxrwxrwx 1 root root 11 Sep 22 17:07 bin64 -> intel64/bin
drwxr-xr-x 2 root root 4096 Sep 22 17:07 binding
drwxr-xr-x 3 root root 4096 Sep 22 17:07 data
drwxr-xr-x 4 root root 4096 Sep 22 17:07 doc
lrwxrwxrwx 1 root root 8 Sep 22 17:07 etc -> ia32/etc
lrwxrwxrwx 1 root root 11 Sep 22 17:07 etc64 -> intel64/etc
drwxr-xr-x 6 root root 4096 Sep 22 17:07 ia32
-rw-r--r-- 1 root root 309 Sep 22 17:07 impi.uninstall.config
lrwxrwxrwx 1 root root 12 Sep 22 17:07 include -> ia32/include
lrwxrwxrwx 1 root root 15 Sep 22 17:07 include64 -> intel64/include
drwxr-xr-x 6 root root 4096 Sep 22 17:07 intel64
lrwxrwxrwx 1 root root 8 Sep 22 17:07 lib -> ia32/lib
lrwxrwxrwx 1 root root 11 Sep 22 17:07 lib64 -> intel64/lib
drwxr-xr-x 3 root root 4096 Sep 22 17:07 man
drwxr-xr-x 6 root root 4096 Sep 22 17:07 mic
-rw-r--r-- 1 root root 28728 Aug 31 07:48 mpi-rtEULA.txt
-rw-r--r-- 1 root root 491 Sep 7 04:12 mpi-rtsupport.txt
-rw-r--r-- 1 root root 28728 Aug 31 07:48 mpiEULA.txt
-rw-r--r-- 1 root root 283 Sep 7 04:12 mpisupport.txt
-rw-r--r-- 1 root root 2770 Aug 31 07:48 redist-rt.txt
-rw-r--r-- 1 root root 1524 Aug 31 07:48 redist.txt
drwxr-xr-x 2 root root 4096 Sep 22 17:07 test
-rw-r--r-- 1 root root 7762 Sep 22 15:28 uninstall.log
-rwxr-xr-x 1 root root 41314 Sep 7 04:12 uninstall.sh
2.2 – 准备
在协处理器上首次运行 MPI 应用之前,请将 MPI 库复制到该系统的每路英特尔® 至强 融核™ 协处理器上的以下目录。在本例中,我们向两路协处理器发出复制命令。第一路协处理器可通过 IP 地址 172.31.1.1 访问,第二路协处理器的 IP 地址为 172.31.2.1。请注意,所有协处理器的 IP 地址都是唯一的,这是因为它们会被视作另外一个唯一的可寻址设备来对待。您可以根据 mic0 或其 IP 地址来查找第一路协处理器,同样,您可以根据 mic1 或其 IP 地址来查找第二路协处理器。
# sudo scp /opt/intel/impi/4.1.0.024/mic/bin/mpiexec mic0:/bin/mpiexec
mpiexec 100% 1061KB 1.0MB/s 00:00
# sudo scp /opt/intel/impi/4.1.0.024/mic/bin/pmi_proxy mic0:/bin/pmi_proxy
pmi_proxy 100% 871KB 871.4KB/s 00:00
# sudo scp /opt/intel/impi/4.1.0.024/mic/lib/libmpi.so.4.1 mic0:/lib64/libmpi.so.4
libmpi.so.4.1 100% 4391KB 4.3MB/s 00:00
# sudo scp /opt/intel/impi/4.1.0.024/mic/lib/libmpigf.so.4.1 mic0:/lib64/libmpigf.so.4
libmpigf.so.4.1 100% 321KB 320.8KB/s 00:00
# sudo scp /opt/intel/impi/4.1.0.024/mic/lib/libmpigc4.so.4.1 mic0:/lib64/libmpigc4.so.4
libmpigc4.so.4.1 100% 175KB 175.2KB/s 00:00
# sudo scp /opt/intel/composer_xe_2013.0.079/compiler/lib/mic/libimf.so mic0:/lib64/libimf.so
libimf.so 100% 2516KB 2.5MB/s 00:01
# sudo scp /opt/intel/composer_xe_2013.0.079/compiler/lib/mic/libsvml.so mic0:/lib64/libsvml.so
libsvml.so 100% 4985KB 4.9MB/s 00:01
# sudo scp /opt/intel/composer_xe_2013.0.079/compiler/lib/mic/libintlc.so.5 mic0:/lib64/libintlc.so.5
libintlc.so.5 100% 128KB 128.1KB/s 00:00
# sudo scp /opt/intel/impi/4.1.0.024/mic/bin/mpiexec mic1:/bin/mpiexec
mpiexec 100% 1061KB 1.0MB/s 00:00
# sudo scp /opt/intel/impi/4.1.0.024/mic/bin/pmi_proxy mic1:/bin/pmi_proxy
pmi_proxy 100% 871KB 871.4KB/s 00:00
# sudo scp /opt/intel/impi/4.1.0.024/mic/lib/libmpi.so.4.1 mic1:/lib64/libmpi.so.4
libmpi.so.4.1 100% 4391KB 4.3MB/s 00:00
# sudo scp /opt/intel/impi/4.1.0.024/mic/lib/libmpigf.so.4.1 mic1:/lib64/libmpigf.so.4
libmpigf.so.4.1 100% 321KB 320.8KB/s 00:00
# sudo scp /opt/intel/impi/4.1.0.024/mic/lib/libmpigc4.so.4.1 mic1:/lib64/libmpigc4.so.4
libmpigc4.so.4.1 100% 175KB 175.2KB/s 00:00
# sudo scp /opt/intel/composer_xe_2013.0.079/compiler/lib/mic/libimf.so mic1:/lib64/libimf.so
libimf.so 100% 2516KB 2.5MB/s 00:01
# sudo scp /opt/intel/composer_xe_2013.0.079/compiler/lib/mic/libsvml.so mic1:/lib64/libsvml.so
libsvml.so 100% 4985KB 4.9MB/s 00:01
# sudo scp /opt/intel/composer_xe_2013.0.079/compiler/lib/mic/libintlc.so.5 mic1:/lib64/libintlc.so.5
libintlc.so.5 100% 128KB 128.1KB/s 00:00
您无须手动复制 MPI 库,只需运行以下脚本即可
#!/bin/sh
export COPROCESSORS="mic0 mic1"
export BINDIR="/opt/intel/impi/4.1.0.024/mic/bin"
export LIBDIR="/opt/intel/impi/4.1.0.024/mic/lib"
export COMPILERLIB="/opt/intel/composer_xe_2013.0.079/compiler/lib/mic"
for coprocessor in `echo $COPROCESSORS`
do
for prog in mpiexec pmi_proxy
do
sudo scp $BINDIR/$prog $coprocessor:/bin/$prog
done
for lib in libmpi.so.4.1 libmpigf.so.4.1 libmpigc4.so.4.1
do
sudo scp $LIBDIR/$lib $coprocessor:/lib64/$lib
done
for lib in libimf.so libsvml.so libintlc.so.5
do
sudo scp $COMPILERLIB/$lib $coprocessor:/lib64/$lib
done
done
对于多卡使用环境,请以点对点的方式配置 MPSS:
# sudo /sbin/sysctl -w net.ipv4.ip_forward=1
net.ipv4.ip_forward = 1
第3章 编译和运行示例MPI程序
该部分包括了一个使用 C 语言编写的示例 MPI 程序。我们将介绍如何针对主机和英特尔® 至强 融核™ 协处理器编译和运行该程序。
英特尔® MPI 库支持三种编程模式:
“仅协处理器”模式:在这种本机模式下,MPI 列仅位于协处理器中。可通过主机或协处理器启动应用。
对称模式:在该模式下,MPI 等级位于主机和协处理器上。
MPI 卸载模式:在该模式下,MPI 列仅位于主机上。MPI 列使用英特尔® C/C++ 编译器或英特尔® Fortran 编译器的卸载功能将部分工作负载卸载到协处理器上。
为便于说明,下面的示例展示了如何在对称模式下构建和运行 MPI 应用。
示例程序使用 Monte Carlo 方法预测 Pi (π) 计算。我们来考虑一个以原点为球心并由一个立方体限制的球体:球体的半径为 r,立方体的边长为 2r。球体和立方体的体积分别为

坐标系统的第一卦限(octant)占了球体和立方体体积的八分之一;该卦限的体积为:

如果我们在该卦限的球体中以一致、随机的方式生成 Nc 点,那么根据下面的比例,我们预计这 Nc 点将位于球体的体积中:

因此,预计 Pi (π) 的值为:
其中 Nc 代表第一卦限的立方体部分中生成的点数,而 Ns 则代表第一卦限的球体部分中的总点数在实施中,列 0(进程)负责将工作在其它 n 列之间划分。每个列均被分配一组工作,而总和则用于估计 Pi 的值。列 0 将 x 轴划分为 n 个相等的段。每列在分配的段中生成 (NC /n) 个点,然后计算球体第一卦限中的点数。

图 1 – 每列在第一卦限中处理单独的部分。伪代码如下所示:
Rank 0 generate n random seed
Rank 0 broadcast all random seeds to n rank
For each rank i [0, n-1]
receive the corresponding seed
set num_inside = 0
For j=0 to Nc / n
generate a point with coordinates
x between [i/n, (i+1)/n]
y between [0, 1]
z between [0, 1]
compute the distance d = x^2 + y^2 + z^2
if distance d <= 1, increment num_inside
Send num_inside back to rank 0
Rank 0 set Ns to the sum of all num_inside
Rank 0 compute Pi = 6 * Nc / Ns
</pre>
编译程序(montecarlo.c)之前,你需要针对编译器以及面向英特尔® 至强 融核™ 协处理器的英特尔 MPI 库创建正确的环境设置。
# source /opt/intel/composer_xe_2013.0.079/bin/compilervars.sh intel64
# source /opt/intel/impi/4.1.0.024/mic/bin/mpivars.sh
针对协处理器构建应用 montecarlo.mic。
# mpiicc –mmic montecarlo.c -o montecarlo.mic
要构建在主机上运行的应用,你需要针对英特尔® 64 英特尔 MPI 库创建环境设置。
# source /opt/intel/impi/4.1.0.024/intel64/bin/mpivars.sh
构建面向主机的应用
# mpiicc montecarlo.c -o montecarlo.host
使用 scp 命令将应用 montecarlo.mic 上传到协处理器上的 /tmp目录。在本例中,我们向两路协处理器发出复制命令。
# sudo scp ./montecarlo.mic mic0:/tmp/montecarlo.mic
montecarlo.mic 100% 15KB 15.5KB/s 00:00
# sudo scp ./montecarlo.mic mic1:/tmp/montecarlo.mic
montecarlo.mic 100% 15KB 15.5KB/s 00:00
启用主机和协处理器之间的 MPI 通信:
# export I_MPI_MIC=enable
使用命令 mpirun 来启动应用。此外,标记 –n 指定了 MPI 进程的数量,标记 –host 指定了设备名称:
# mpirun –n <# of processes> -host <hostname> <application>
我们可以在多台主机上运行应用,具体方法是使用 “:”将其隔开。第一个 MPI 列 (rank 0) 总是在命令的第一个部分启动:
# mpirun –n <# of processes> -host <hostname1> <application> : –n <# of processes> -host <hostname2> <application>
这将在 hostname1 上启动 rank 0。
现在在主机上运行应用。下面所示的 mpirun 命令启动带有两个列(主机上)、3 个列(协处理器 MIC0 上)和 5 个列(协处理器 MIC1 上)的应用:
# mpirun -n 2 -host knightscorner1 ./montecarlo.host \
: -n 3 -host mic0 /tmp/montecarlo.mic \
: -n 5 -host mic1 /tmp/montecarlo.mic
Hello world: rank 0 of 10 running on knightscorner1
Hello world: rank 1 of 10 running on knightscorner1
Hello world: rank 2 of 10 running on knightscorner1-mic0
Hello world: rank 3 of 10 running on knightscorner1-mic0
Hello world: rank 4 of 10 running on knightscorner1-mic0
Hello world: rank 5 of 10 running on knightscorner1-mic1
Hello world: rank 6 of 10 running on knightscorner1-mic1
Hello world: rank 7 of 10 running on knightscorner1-mic1
Hello world: rank 8 of 10 running on knightscorner1-mic1
Hello world: rank 9 of 10 running on knightscorner1-mic1
Elapsed time from rank 0: 14.79 (sec)
Elapsed time from rank 1: 14.90 (sec)
Elapsed time from rank 2: 219.87 (sec)
Elapsed time from rank 3: 218.24 (sec)
Elapsed time from rank 4: 218.29 (sec)
Elapsed time from rank 5: 218.94 (sec)
Elapsed time from rank 6: 218.74 (sec)
Elapsed time from rank 7: 218.42 (sec)
Elapsed time from rank 8: 217.93 (sec)
Elapsed time from rank 9: 217.35 (sec)
Out of 4294967295 points, there are 2248861895 points inside the sphere => pi= 3.141623973846
在对称模式下,一种简单的方法是根据 I_MPI_MIC_POSTFIX 环境变量,针对 mpirun 命令使用 –machinefile 参数。在这种情况下,请确保所有可执行文件均位于主机以及 MIC0 和 MIC1 卡的相同位置。
在卡上运行时,I_MPI_MIC_POSTFIX 环境变量会命令库添加.mic 后缀(因为这里的可执行文件被称为 montecarlo.mic)。
# export I_MPI_MIC_POSTFIX=.mic
:现在请在您的主机文件中设置列映射(使用 <host>:<#_ranks> 格式):
# cat hosts_file
knightscorner1:2
mic0:3
mic1:5
运行您的可执行文件:
# cp ./montecarlo.host /tmp/montecarlo
# mpirun -machinefile hosts_file /tmp/montecarlo
该语法有一项优势 — 当决定更改列数或需要添加更多的卡时,只需编辑 hosts_file 即可。
或者,您也可以在主机上启动仅在协处理器 mic0 和 mic1上运行的应用:
# mpirun -n 3 -host mic0 /tmp/montecarlo.mic : -n 5 -host mic1 \ /tmp/montecarlo.mic
Hello world: rank 0 of 8 running on knightscorner1-mic0
Hello world: rank 1 of 8 running on knightscorner1-mic0
Hello world: rank 2 of 8 running on knightscorner1-mic0
Hello world: rank 3 of 8 running on knightscorner1-mic1
Hello world: rank 4 of 8 running on knightscorner1-mic1
Hello world: rank 5 of 8 running on knightscorner1-mic1
Hello world: rank 6 of 8 running on knightscorner1-mic1
Hello world: rank 7 of 8 running on knightscorner1-mic1
Elapsed time from rank 0: 273.71 (sec)
Elapsed time from rank 1: 273.20 (sec)
Elapsed time from rank 2: 273.66 (sec)
Elapsed time from rank 3: 273.84 (sec)
Elapsed time from rank 4: 273.53 (sec)
Elapsed time from rank 5: 273.24 (sec)
Elapsed time from rank 6: 272.59 (sec)
Elapsed time from rank 7: 271.64 (sec)
Out of 4294967295 points, there are 2248861679 points inside the sphere => pi= 3.141623497009
另外,您也可以向协处理器 mic0 发出 ssh 命令并启动那里的应用:
# ssh mic0
# mpiexec -n 3 /tmp/montecarlo.mic
Hello world: rank 0 of 3 running on knightscorner1-mic0
Hello world: rank 1 of 3 running on knightscorner1-mic0
Hello world: rank 2 of 3 running on knightscorner1-mic0
Elapsed time from rank 0: 732.09 (sec)
Elapsed time from rank 1: 727.86 (sec)
Elapsed time from rank 2: 724.82 (sec)
Out of 4294967295 points, there are 2248845386 points inside the sphere => pi= 3.141600608826
附录示例 MPI 程序的代码如下所示。
001/*002// Copyright 2003-2012 Intel Corporation. All Rights Reserved.003//004// The source code contained or described herein and all documents related005// to the source code ("Material") are owned by Intel Corporation or its006// suppliers or licensors. Title to the Material remains with Intel Corporation007// or its suppliers and licensors. The Material is protected by worldwide008// copyright and trade secret laws and treaty provisions. No part of the009// Material may be used, copied, reproduced, modified, published, uploaded,010// posted, transmitted, distributed, or disclosed in any way without Intel's011// prior express written permission.012//013// No license under any patent, copyright, trade secret or other intellectual014// property right is granted to or conferred upon you by disclosure or delivery015// of the Materials, either expressly, by implication, inducement, estoppel016// or otherwise. Any license under such intellectual property rights must017// be express and approved by Intel in writing.018019020#******************************************************************************021# Content: (version 0.5)022# Based on a Monto Carlo method, this MPI sample code uses volumes to023# estimate the number PI.024#025#*****************************************************************************/026#include <stdlib.h>027#include <stdio.h>028#include <math.h>029#include <time.h>030#include <math.h>031032#include "mpi.h"033034#define MASTER 0035#define TAG_HELLO 4036#define TAG_TEST 5037#define TAG_TIME 6038039intmain(intargc,char*argv[])040{041inti, id, remote_id, num_procs;042043MPI_Status stat;044intnamelen;045charname[MPI_MAX_PROCESSOR_NAME];046047// Start MPI.048if(MPI_Init (&argc, &argv) != MPI_SUCCESS)049{050printf("Failed to initialize MPIn");051return(-1);052}053// Create the communicator, and retrieve the number of processes.054MPI_Comm_size (MPI_COMM_WORLD, &num_procs);055056// Determine the rank of the process.057MPI_Comm_rank (MPI_COMM_WORLD, &id);058059// Get machine name060MPI_Get_processor_name (name, &namelen);061062if(id == MASTER)063{064printf("Hello world: rank %d of %d running on %sn", id, num_procs, name);065066for(i = 1; i<num_procs; i++)067{068MPI_Recv (&remote_id, 1, MPI_INT, i, TAG_HELLO, MPI_COMM_WORLD, &stat);069MPI_Recv (&num_procs, 1, MPI_INT, i, TAG_HELLO, MPI_COMM_WORLD, &stat);070MPI_Recv (&namelen, 1, MPI_INT, i, TAG_HELLO, MPI_COMM_WORLD, &stat);071MPI_Recv (name, namelen+1, MPI_CHAR, i, TAG_HELLO, MPI_COMM_WORLD, &stat);072073printf("Hello world: rank %d of %d running on %sn", remote_id, num_procs, name);074}075}076else077{078MPI_Send (&id, 1, MPI_INT, MASTER, TAG_HELLO, MPI_COMM_WORLD);079MPI_Send (&num_procs, 1, MPI_INT, MASTER, TAG_HELLO, MPI_COMM_WORLD);080MPI_Send (&namelen, 1, MPI_INT, MASTER, TAG_HELLO, MPI_COMM_WORLD);081MPI_Send (name, namelen+1, MPI_CHAR, MASTER, TAG_HELLO, MPI_COMM_WORLD);082}083084// Rank 0 distributes seek randomly to all processes.085doublestartprocess, endprocess;086087intdistributed_seed = 0;088int*buff;089090buff = (int*)malloc(num_procs *sizeof(int));091092unsignedintMAX_NUM_POINTS =pow(2,32) - 1;093unsignedintnum_local_points = MAX_NUM_POINTS / num_procs;094095if(id == MASTER)096{097srand(time(NULL));098099for(i=0; i<num_procs; i++)100{101distributed_seed =rand();102buff[i] = distributed_seed;103}104}105106// Broadcast the seed to all processes107MPI_Bcast(buff, num_procs, MPI_INT, MASTER, MPI_COMM_WORLD);108109// At this point, every process (including rank 0) has a different seed. Using their seed,110// each process generates N points randomly in the interval [1/n, 1, 1]111startprocess = MPI_Wtime();112113srand(buff[id]);114115unsignedintpoint = 0;116unsignedintrand_MAX = 128000;117floatp_x, p_y, p_z;118floattemp, temp2, pi;119doubleresult;120unsignedintinside = 0, total_inside = 0;121122for(point=0; point<num_local_points; point++)123{124temp = (rand() % (rand_MAX+1));125p_x = temp / rand_MAX;126p_x = p_x / num_procs;127128temp2 = (float)id / num_procs;// id belongs to 0, num_procs-1129p_x += temp2;130131temp = (rand() % (rand_MAX+1));132p_y = temp / rand_MAX;133134temp = (rand() % (rand_MAX+1));135p_z = temp / rand_MAX;136137// Compute the number of points residing inside of the 1/8 of the sphere138result = p_x * p_x + p_y * p_y + p_z * p_z;139140if(result <= 1)141{142inside++;143}144}145146doubleelapsed = MPI_Wtime() - startprocess;147148MPI_Reduce (&inside, &total_inside, 1, MPI_UNSIGNED, MPI_SUM, MASTER, MPI_COMM_WORLD);149150151#if DEBUG152printf("rank %d counts %u points inside the spheren", id, inside);153#endif154if(id == MASTER)155{156doubletimeprocess[num_procs];157158timeprocess[MASTER] = elapsed;159printf("Elapsed time from rank %d: %10.2f (sec) n", MASTER, timeprocess[MASTER]);160161for(i=1; i<num_procs; i++)162{163// Rank 0 waits for elapsed time value164MPI_Recv (&timeprocess[i], 1, MPI_DOUBLE, i, TAG_TIME, MPI_COMM_WORLD, &stat);165printf("Elapsed time from rank %d: %10.2f (sec) n", i, timeprocess[i]);166}167168temp = 6 * (float)total_inside;169pi = temp / MAX_NUM_POINTS;170printf("Out of %u points, there are %u points inside the sphere => pi=%16.12fn", MAX_NUM_POINTS, total_inside, pi);171}172else173{174// Send back the processing time (in second)175MPI_Send (&elapsed, 1, MPI_DOUBLE, MASTER, TAG_TIME, MPI_COMM_WORLD);176}177178free(buff);179180// Terminate MPI.181MPI_Finalize();182183return0;184}

Loc Q Nguyen 获得了达拉斯大学 MBA 学位、麦吉尔大学电子工程专业硕士学位以及蒙特利尔理工学院电子工程专业学士学位。他目前在英特尔公司软件及服务事业部担任软件工程师。他研究的领域包括计算网络、计算机图形和并行处理。
