2017-03-17 158 views
1

我有一个很奇怪的问题。 我甚至不知道我是否可以向您提供所有需要回答我的问题的信息;万一缺少什么东西,请告诉我。性能比较MPI vs OpenMP

我会像这样使用MPI代码:

#include <mpi.h> 
#include <cmath> 
#include <stdio.h> 
#include <stdlib.h> 
#include <time.h> 
#include <string.h> 
#include <cstdlib> 
#include <fstream> 
#include <sstream> 
#include <iomanip> 
#include <iostream> 
#include <stdexcept> 
#include <algorithm> 
#include "mkl.h" 
double *gradient_D = new double[K*M]; 
double *DX = new double[M*N]; 
double gradientD_time = MPI_Wtime(); 
for (int j = 0; j < K; j++){ 
    for (int i = 0; i < M; i++){ 
     gradient_D[j*M+i] = 0; 
     for (int k = 0; k < n; k++) 
      gradient_D[i+M*j] += DX[i+k*M]; 
     } 
    } 
double gradientD_total_time = (MPI_Wtime() - gradientD_time); 
printf("Gradient D total = %f \n", gradientD_total_time); 

这颂歌都无所谓代码的含义是:我只是跑三为循环和evaulating的CPU时间。 在cmake的我写了下面的命令:

project(mpi_algo) 
cmake_minimum_required(VERSION 2.8) 
set(CMAKE_CXX_COMPILER "mpicxx") 
set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS) 
set(CMAKE_CXX_FLAGS "-cxx=icpc -mkl=sequential") 
add_executable(mpi_algo main.cpp) 

,我运行代码:

mpirun -np 1 ./mpi_algo 

在那之后,我运行一个类似的代码中,我做同样的操作,但使用OpenMP代替MPI:

#include <omp.h> 
#include <cmath> 
#include <stdio.h> 
#include <stdlib.h> 
#include <time.h> 
#include <string.h> 
#include <cstdlib> 
#include <fstream> 
#include <sstream> 
#include <iomanip> 
#include <iostream> 
#include <stdexcept> 
#include <algorithm> 
#include "mkl.h" 
double *gradient_D = new double[K*M]; 
double *DX = new double[M*N]; 
double gradientD_time = omp_get_wtime(); 
for (int j = 0; j < K; j++){ 
    for (int i = 0; i < M; i++){ 
     gradient_D[j*M+i] = 0; 
     for (int k = 0; k < n; k++) 
      gradient_D[i+M*j] += DX[i+k*M]; 
     } 
    } 
double gradientD_total_time = (omp_get_wtime() - gradientD_time); 
printf("Gradient D total = %f \n", gradientD_total_time); 

您可以看到代码中存在细微差异。 这是CMake的:

project(openmp_algo) 
cmake_minimum_required(VERSION 2.8) 
set(CMAKE_CXX_COMPILER "icc") 
set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS) 
set(CMAKE_CXX_FLAGS "-qopenmp -mkl=sequential") 
add_executable(openmp_algo main.cpp) 

,我运行代码:

./openmp_algo

现在,我无法解释的是,与MPI代码需要1秒左右运行。另一个应该是相同的,大约需要20秒。

你能否请某人解释我为什么?

编辑:常量M,N,n,k对理解问题无关紧要。他们只是定义了数组的维度。

+2

你编译优化?没有他们,这是一个毫无意义的比较;一个编译器可能会默认某种级别的优化,并优化大部分循环(因为结果未被使用,循环实际上可能会被更高的优化级别完全舍弃),另一个编译器可能会做所有的工作然后抛弃它。这不是一个[MCVE];我们不知道'gradient_D_loc'的定义在哪里,任何常量是什么,等等。 – ShadowRanger

+0

我不知道你指的是什么。 实际上在整个代码中使用了该循环的结果。编辑: – Mobius88

+0

我编辑:'gradient_D_loc'应该只是'gradient_D' – Mobius88

回答

0

由于您没有提供有关环境的更多细节,因此我会大胆猜测以尝试给出解释。首先,让我们讲几句话:

  • 你看似相同的只是什么也不做,这样一个聪明的编译器完全有权优化掉你的计算循环,只是做印刷;
  • 你OpenMP的代码被编译,因此其优化程度将是默认-O2(减去视为不是线程安全的默认情况下,使用-qopenmp将禁用额外的优化香草icc(对于C++代码顺便说一句奇怪的选择);
  • 您的MPI代码与普通mpicxx编译,这将在内部调用icpc如编译器

这是我怀疑是这里的关键的mpicxx:的确,mpicxx是只是一个包装,以实际的编译器,还会设置一些包含路径,一些库路径和lis吨,但也可能会设置一些额外的优化选项。例如,在某些情况下,安装MPI库时使用的优​​化选项将保留在mpicxx包装中,并在编译代码时默认默认使用...

因此,这里是我的猜测,您mpicxx集合中其他的-O3优化选项,因此,编译器会优化掉了MPI的循环,而您为您的OpenMP代码默认-O2没有做到这一点。因此,在计算实际的OpenMP执行循环时,您的计时非常多 - 对于MPI代码来说没有任何问题。

只是一个猜测,但这似乎够公平。一个好的测试将是检查什么mpicxx -cxx=icpc -show会给你...

+0

好的,我会检查。 但是你知道如何改变这两种编译器吗?这两种编码之间的比较是合理的。 我应该降低(不知道如何)到'-O2'' mpicxx'或者我应该增加到'-O3'(我不知道怎么说)'icpc'编译器? – Mobius88