【发布时间】:2017-08-09 14:43:46
【问题描述】:
我有一个很奇怪的问题。 我什至不知道我是否可以为您提供回答我的问题所需的所有信息;如果有什么遗漏,请告诉我。
我使用 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);
代码的含义并不重要:我只是运行三个 for 循环并评估 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 对理解问题无关紧要。他们只是定义了数组的维度。
【问题讨论】:
-
您编译时是否启用了优化?没有它们,这是毫无意义的比较;一个编译器可能会默认进行某种程度的优化并优化大部分循环(由于未使用结果,因此实际上可以使用更高的优化级别完全删除循环),另一个编译器可能正在完成所有工作然后将其丢弃。这不是minimal reproducible example 也无济于事;我们不知道
gradient_D_loc是在哪里定义的,是什么常量等等。 -
我不知道你指的是什么。实际上在整个代码中都使用了该循环的结果。
-
我编辑了:
gradient_D_loc应该只是gradient_D -
编译器采用标志来启用优化(大多数默认生成未优化的代码,但不是全部)。将时序结果与关闭或不同级别的优化进行比较不会给您有用的结果。例如,
icc将-O#(#为 0-3)用于越来越高的优化级别,加上-fast用于“极端优化”。由于mpicxx似乎在这里包装了icpc,它会传递类似的选项。看起来像-O2 -xHostis recommended withicc/icpc。 -
为什么在 OpenMP 示例中使用
icc作为 C++ 编译器?
标签: c++ performance time mpi openmp