我在 Virtual box 上运行 Ubuntu 12,我正在使用 GCC 编译这个具有简单 OpenMp pragmas 的简单 C 程序:
#include <stdio.h>
#include <omp.h>
#define MAX 10000000000
void main()
{
unsigned long long i,j,k,l;
int threadnumber;
#pragma omp parallel shared(i,j,k,l)
{
threadnumber = omp_get_thread_num();
if(threadnumber == 0)
{
for(i = 0; i < (MAX / 4); i++)
;
}
else if(threadnumber == 1)
{
for(j = (MAX / 4); j < (MAX / 2); j++)
;
}
else if(threadnumber == 2)
{
for(k = (MAX / 2); k < (3 * (MAX / 4));k++)
;
}
else
{
for(l = (3 * (MAX / 4)); l < MAX; l++)
;
}
}
}
我的处理器是 Intel Core i5。 该程序确实在并行工作(通过添加一些 printf()s 验证),我已将环境变量(OMP_NUM_THREADS)设置为 4。 问题是代码比这个不并行的代码要花更多的时间:
#include <stdio.h>
#define MAX 10000000000
void main()
{
unsigned long long i;
for(i = 0; i < MAX; i++)
;
}
我还尝试在两个版本的循环之前和之后添加 clock()
调用,并且我在并行版本中获得了更长的时间。
我还尝试使用 time ./a.out
来测量时间,并且我得到(仅在并行版本中)与 clock() 返回的时间不同的“实时”时间
!
我已经在 visual studio 上编译了这两个代码,结果如下:
- 在 Debug模式下:两种代码的时间几乎相等,并且该时间接近 GCC 的时间。
- 在 Release模式下:两种代码都更快,并行代码在时间上有很大的改进。 问题简而言之:
- 我想以与 visual studio 编译器的发布版本相同的效率并行运行该程序。
2) 除了
"-fopenmp"
之外,是否有我应该传递给 GCC 的参数或选项,以使其构建与 visual studio 完全一样的发布版本。 3) 我想知道这是 Ubuntu 问题还是 GCC 问题还是什么???
P.S:我已经尝试在安装了五笔的 Ubuntu 和作为独立操作系统的 Ubuntu(在 ext4 文件系统上)和同一平台上运行相同的过程,我得到了相同的结果。
最佳答案
我真的不明白为什么 SO 上每个新的 OpenMP 相关问题都包含使用 clock()
来(错误地)测量挂钟执行时间的代码,前提是 OpenMP 有一个可移植的高分辨率计时器,可通过调用 omp_get_wtime()
?
首先,在并行区域内使用共享变量作为循环计数器是一个非常糟糕的想法。 Here这就是为什么,尽管您有一个 Nehalem 或更高版本的基于微架构的 CPU,这使得这不是一个问题。
其次,Visual Studio 在调试和发布配置中应用不同的优化级别。在 Debug模式下禁用优化 (/Od
),而在 Release模式下启用速度优化 (/O2
)。您说在 Debug模式下 VS 代码的运行速度与 GCC 代码一样快。这可能意味着您运行 GCC 时其默认优化级别为无优化。使用 -O2
甚至使用 -O3
进行编译,以获得与 VS 在 Release模式下生成的代码相同的代码。
第三,您在虚拟机中运行 Ubuntu。虚拟机可以访问多少个 CPU?
第四,为什么要重新实现 OpenMP 并行 for
工作共享指令?
关于c - 使用 GCC 时 OpenMP 没有进行实际的并行处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11250916/