基本的openmp程序运行速度较慢

时间:2015-11-20 13:56:44

标签: c++ parallel-processing openmp

我想让我的程序运行得更快,所以我会使用并行计算。在此之前,我尝试使用简单的for循环,但运行速度较慢。

在打开mp之前

int a[100000] = { 0 };
clock_t begin = clock();

for (int i = 0; i < 100000; i++)
{
    a[i] = i;
}


clock_t end = clock();
double elapsed_secs = double(end - begin) / CLOCKS_PER_SEC;
printf("%lf", elapsed_secs);

打开mp后:

int a[100000] = { 0 };
clock_t begin = clock();


#pragma omp parallel for
for (int i = 0; i < 100000; i++)
{
    a[i] = i;
}


clock_t end = clock();
double elapsed_secs = double(end - begin) / CLOCKS_PER_SEC;
printf("%lf", elapsed_secs);

2 个答案:

答案 0 :(得分:2)

你说你的代码运行速度较慢,但​​实际上你并不知道。原因是您使用clock()来测量时间,此函数计算当前线程 CPU 时间,并可能计算它产生的所有线程之一 。为了评估加速,您需要测量的是经过的挂钟时间。为此,OpenMP为您提供omp_get_wtime()。尝试在代码上使用它,然后您真的知道您的代码是否从OpenMP中获得任何好处。

现在,让我们清楚一点,你的代码只是写在内存中。因此很有可能您很快就会使内存带宽饱和。因此,除非您有多个内存控制器,否则在这种情况下添加线程不太可能获得太多收益。请查看this answer以说服自己。

最后,确保在退出代码之前对数据执行某些操作,否则,编译器可能只是优化它,导致代码几乎没有做任何事情(但是执行速度非常快)。 / p>

答案 1 :(得分:1)

要成功完成第一个OpenMP并行(多线程)代码示例,您需要从以下两个角度改进测试用例:

  1. 让您的示例可测试。要做到这一点:

    • 确保您的代码足够复杂,不会让编译器有机会“优化”整个循环(即防止编译器用单个表达式替换整个循环)
    • 您可能最终需要引入函数包装循环并在运行时将参数传递给此函数(通过argc / argv)以使编译器混淆,同时保持代码非常简单
    • 确保使用正确的编译标志(-O2 -fopenmp用于GCC,其他标志用于其他编译器)
    • 确保你的循环花费足够的时间并且你使用适当的方法来测量循环中花费的时间(其他受访者,包括Gilles,alrady指出它非常好)。
  2. 确保你的循环在每次循环迭代中都做了足够的(理想的计算)工作(即添加,乘法等),以便各种 开销 与在OpenMP运行时库中进行一些底层工作相关联(需要“安排”/计划/分配线程之间的迭代)不是“更大”而不是有用工作量< / strong>在一堆循环迭代中完成。 第二和第三维基百科OpenMP' parallel for examples已经足够大,可以满足给定的标准(而你的例子并不令人满意)。您只需遵循维基百科示例即可帮助您获得一些基本的理解。

  3. 在你学习了基础知识之后,接下来的步骤将是(a)理解“数据竞赛”/“竞争条件”/“循环携带依赖关系”和(b)理解#pragma omp parallel和#pragma之间的“差异” omp for(再次,你需要从书籍或基本的OpenMP课程中找到简单的例子)。

    (老实说,所有其他主题,如OpenMP不平衡,动态与静态,内存带宽,只有在您花费至少几天阅读/练习更简单的概念后才有意义)