安装mpi
boost是一个c++的库, 里面虽然实现了mpi的一些接口, 但是要使用的话, 仍然需要配合mpi使用
- 寻找yum源中的mpich包
yum list mpich*
- 找到x86_64的devel版本进行安装
yum install mpich-3.2-devel.x86_64
- 寻找mpich包所包含的文件
rpm -ql mpich-3.2-devel.x86_64
- 找到mpich的二进制执行文件夹
/usr/lib64/mpich-3.2/bin
- 将二进制执行文件添加到环境变量的搜索路径中
vim ~/.bash_profile
PATH=$PATH:/usr/lib64/mpich-3.2/bin/
- 使环境变量配置生效
source ~/.bash_profile
安装编译boost
- 下载boost库文件
https://dl.bintray.com/boostorg/release/
选择需要下载的版本(.tar.gz文件), 直接下载或者使用wget工具均可
- 解压文件
tar zxvf boost_1_73_0.tar.gz
- 运行引导脚本程序
cd boost_1_73_0
./bootstrap.sh --with-libraries=all --with-toolset=gcc
- all 表示编译所有库文件, 可以指定, 多个之间使用逗号分隔
- 在生成的
project-config.jam
文件中添加using mpi ;
- 否则之后没有mpi 的静态文件
- 进行编译
./b2 toolset=gcc
时间较长
- 安装
./b2 install --prefix=/usr
- 头文件在
/usr/include/boost
, 链接文件在/usr/lib
配置环境变量
- 配置头文件和连接库的搜索路径
vim /etc/profile
export CPLUS_INCLUDE_PATH=/usr/include/boost:$CPLUS_INCLUDE_PATH export LIBRARY_PATH=/usr/lib:$LIBRARY_PATH export LD_LIBRARY_PATH=/usr/lib:$LD_LIBRARY_PATH export C_INCLUDE_PATH=/usr/include/boost:$C_INCLUDE_PATH
- CPLUS_INCLUDE_PATH c++头文件搜索路径
- C_INCLUDE_PATH c头文件搜索路径
- LIBRARY_PATH 静态链接库搜索路径
- LD_LIBRARY_PATH 动态链接库搜索路径
boost库中的mpi使用 (特定语法)
- 使用mpi时
mpic++ main.cpp -o main -lboost_mpi
mpirun -np 4 ./main
#include <boost/mpi.hpp>
#include <iostream>
int main(int argc, char* argv[])
{
boost::mpi::environment env(argc, argv);
boost::mpi::communicator world;
if (world.rank() == 0) {
world.send(1, 9, 32);
world.send(2, 9, 33);
} else {
int data;
world.recv(0, 9, data);
std::cout << "In process " << world.rank( ) << "with data " << data
<< std::endl;
}
return 0;
}
In process 1 with data 32
In process 2 with data 33
- 使用threads时
g++ main.cpp -o main -lpthread
#include <boost/thread/thread.hpp> //包含boost头文件
#include <iostream>
#include <cstdlib>
using namespace std;
volatile bool isRuning = true;
void func1()
{
static int cnt1 = 0;
while(isRuning)
{
cout << "func1:" << cnt1++ << endl;
sleep(1);
}
}
void func2()
{
static int cnt2 = 0;
while(isRuning)
{
cout << "\tfunc2:" << cnt2++ << endl;
sleep(2);
}
}
int main()
{
boost::thread thread1(&func1);
boost::thread thread2(&func2);
system("read");
isRuning = false;
thread2.join();
thread1.join();
cout << "exit" << endl;
return 0;
}
使用boost.mpi实现梯形积分法
- 实验目的
- 采用梯形积分法求曲线与坐标轴围成的面积
- 实验设计
- 计算由曲线y=x^3与直线x=0, x=1, y=0围成的面积
- 将(0, 1) 分成1000等份, 四个进程平均分配任务共同计算这1000个梯形积分
- 进程1,2,3将计算结果通过send函数发送会进程0
- 进程0使用recv函数接受进程1,2,3发送的结果, 并且将所有结果累加
- 采用elapsed()函数计算耗时
#include <iostream>
#include <boost/mpi.hpp>
#include <cmath>
double f(double);
void* serial_area(double, double, int, double*);
int main(int argc, char * argv[]) {
boost::mpi::environment env(argc, argv);
boost::mpi::communicator world;
boost::mpi::timer t;
double start ,end;
double a = 0.0;
double b = 1.0;
int n = 1000;
double h = (b - a) / n;
int seg = n / 4;
double result;
double temp_result;
if (world.rank() == 0) {
start = t.elapse();
serial_area(a, (world.rank() + 1) * seg * h, seg, &result);
for (int i = 1; i < 4; i++) {
world.recv(i, 9, &temp_result, 1);
result += temp_result;
}
end = t.elapse();
std::cout<<"time: "<<end - start<<"s"<<std::endl;
std::cout<<"result: "<<result<<std::endl;
} else {
serial_area(world.rank() * seg * h, (world.rank() + 1) * seg * h, seg, &result);
world.send(0, 9, &result, 1);
}
return 0;
}
double f(double x) {
return pow(x, 2);
}
void* serial_area(double a, double b, int n, double* global_val) {
double h, approx;
h = (b - a) / n;
approx = (f(a) + f(b)) / 2;
for (int i = 1; i < n; i++) {
approx += f(a + i * h);
}
*global_val = approx * h;
return NULL;
}
time: 0.0891421s
result: 0.333333