正如本科的一个老师说的“那些第一门语言选择学习c语言的人来说, 他们很难使用面向对象的观点去思考问题” 。虽然我的“面向对象观”仍然薄弱,但从c++转换到c还是很痛苦的事情。原因包括(但不限于):
1. c太低级,缺少可重用的库。就算我们需要一个Stack,也需要自己重新实现,或者在网上搜寻,浪费大量时间。
2. 缺少模板,导致void*之类的大量使用,类型安全无法保证。这里,更差的选择是使用typedef,使得重用困难重重。
3.缺少类。习惯用类来实现抽象概念的人估计无法忍受。更加不要说使用有趣而精致的设计模式了。
4.编程习惯问题。当你想输出的时候,你就好不犹豫的键入"cout",然后突然发现自己在使用c,不得不一阵狂按backspace,然后键入printf。更糟糕的是那个可变长的参数列表使你总是与前面的字符串格式对不上号。其实这个都是次要,像很少使用const,大量使用define, void*以及没有reference语义等都会使你感觉糟糕。
由于MPICH与C++的io库有冲突,所以在C++中使用MPICH需要一些特别的修改。
如果在cpp文件中使用头文件mpi.h,则编译的时候会出现以下错误:
SEEK_SET is #defined but must not be for the C++ binding of MPI
可以通过添加编译参数 -DMPICH_IGNORE_CXX_SEEK来修正这个bug(还有另外一个方法,但不推荐使用)。
比如:
#include <mpi.h>
#include <iostream>
#include <string>
using namespace std;
int main(int argc, char **argv){
int id, nprocs;
string hello = "Hello world!";
int strlen = hello.length();
char rcv_buffer[128];
MPI_Status status;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
MPI_Comm_rank(MPI_COMM_WORLD, &id);
if(nprocs != 2){
cout<<"2 processes are needed to run this program./n";
}
else
{
if(!id){
//hello.c_str() return a const char* value, so
//you should first convert it to char*.
MPI_Send((const_cast<char*>(hello.c_str()))
, strlen + 1, MPI_CHAR, 1, 0, MPI_COMM_WORLD);
}
else{
//No way to directy store the data in a string type variable
MPI_Recv(rcv_buffer, strlen + 1, MPI_CHAR, 0, 0,
MPI_COMM_WORLD, &status);
hello = rcv_buffer;
cout<<"process "<<id<<"#: received message '"
<<hello<<"' from process 0#/n";
}
}
MPI_Finalize();
}
进程0向进程1发送字符串Hello world!,进程1把这个字符串打印在标准输出。
可以在命令行使用
mpicxx -DMPICH_IGNORE_CXX_SEEK hello.cpp -o hello
编译上述程序。
然后在命令行键入mpiexec -n 2 hello,即可执行。
源代码以及make文件在http://xiao-desktop/svn/robinvane/cpp/hello_mpi/
1. c太低级,缺少可重用的库。就算我们需要一个Stack,也需要自己重新实现,或者在网上搜寻,浪费大量时间。
2. 缺少模板,导致void*之类的大量使用,类型安全无法保证。这里,更差的选择是使用typedef,使得重用困难重重。
3.缺少类。习惯用类来实现抽象概念的人估计无法忍受。更加不要说使用有趣而精致的设计模式了。
4.编程习惯问题。当你想输出的时候,你就好不犹豫的键入"cout",然后突然发现自己在使用c,不得不一阵狂按backspace,然后键入printf。更糟糕的是那个可变长的参数列表使你总是与前面的字符串格式对不上号。其实这个都是次要,像很少使用const,大量使用define, void*以及没有reference语义等都会使你感觉糟糕。
由于MPICH与C++的io库有冲突,所以在C++中使用MPICH需要一些特别的修改。
如果在cpp文件中使用头文件mpi.h,则编译的时候会出现以下错误:
SEEK_SET is #defined but must not be for the C++ binding of MPI
可以通过添加编译参数 -DMPICH_IGNORE_CXX_SEEK来修正这个bug(还有另外一个方法,但不推荐使用)。
比如:
#include <mpi.h>
#include <iostream>
#include <string>
using namespace std;
int main(int argc, char **argv){
int id, nprocs;
string hello = "Hello world!";
int strlen = hello.length();
char rcv_buffer[128];
MPI_Status status;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
MPI_Comm_rank(MPI_COMM_WORLD, &id);
if(nprocs != 2){
cout<<"2 processes are needed to run this program./n";
}
else
{
if(!id){
//hello.c_str() return a const char* value, so
//you should first convert it to char*.
MPI_Send((const_cast<char*>(hello.c_str()))
, strlen + 1, MPI_CHAR, 1, 0, MPI_COMM_WORLD);
}
else{
//No way to directy store the data in a string type variable
MPI_Recv(rcv_buffer, strlen + 1, MPI_CHAR, 0, 0,
MPI_COMM_WORLD, &status);
hello = rcv_buffer;
cout<<"process "<<id<<"#: received message '"
<<hello<<"' from process 0#/n";
}
}
MPI_Finalize();
}
进程0向进程1发送字符串Hello world!,进程1把这个字符串打印在标准输出。
可以在命令行使用
mpicxx -DMPICH_IGNORE_CXX_SEEK hello.cpp -o hello
编译上述程序。
然后在命令行键入mpiexec -n 2 hello,即可执行。
源代码以及make文件在http://xiao-desktop/svn/robinvane/cpp/hello_mpi/