【问题标题】:OpenMP does not provide speedup for simple programOpenMP 不为简单程序提供加速
【发布时间】:2018-08-10 01:52:20
【问题描述】:

我刚开始用 C++ 学习 OpenMP,我使用了一个非常简单的程序来检查我是否可以通过并行化程序来获得一些加速:

#include <iostream>
#include <ctime>
#include "omp.h"


int main() {
    const uint N = 1000000000;
    clock_t start_time = clock();
    #pragma omp parallel for
    for (uint i = 0; i < N; i++) {
        int x = 1+1;
    }

    clock_t end_time = clock();
    std::cout << "total_time: " << double(end_time - start_time) / CLOCKS_PER_SEC << " seconds." << std::endl;
}

程序在没有并行 #pragma 的情况下需要 2.2 秒,在并行 #pragma 4 线程情况下需要 2.8 秒。我在程序中犯了什么错误?我的编译器是clang++ 6.0,电脑是Macbook Pro,2.6G i5 CPU,MacOS 10.13.6。

编辑:

我意识到我使用了错误的函数来测量执行时间。我应该使用库 chrono 库中的 high_resolution_clock 而不是库 ctime 中的 clock()。在这种情况下,我得到 1 个线程 80 秒,2 个线程 47 秒,3 个线程 35 秒。由于程序是令人尴尬的并行,因此加速是否应该比我在这里得到的更好?

【问题讨论】:

  • 你编译的时候优化到最大了吗?我很惊讶代码需要任何时间来执行,一个体面的优化编译器会看到整个循环是死代码(结果未被使用)并将其优化为遗忘。
  • 另外,使用omp_get_wtime()代替clock来测量时间。更多信息here
  • 除非您有 NUMA 平台,例如双CPU,即使是单线程也可能会占用全部内存带宽。如果没有 OpenMP,一个完整的优化编译器(如果它没有将非并行循环作为死代码消除)可能会替换一个自动转移到非临时存储的 memset 调用,这样您就不需要在存储之前读取内存.目前尚不清楚使用 uint 代替 int 是否会妨碍优化(如果使用 32 位模式,几乎肯定会出现问题)。
  • @HighPerformanceMark 当然,如果使用任何优化,那么代码不会花时间,但我只想让代码在循环内做一些事情,所以在这个测试中没有使用优化。在这种情况下,我不应该通过使用的线程数(假设我有足够的 CPU)获得线性加速吗??

标签: openmp


【解决方案1】:

与并行编程中的任何事情一样,创建新线程需要启动成本。对于简单的程序,创建和管理线程的开销通常很大,与在单线程中运行程序相比,它实际上会减慢目标程序的速度。

换句话说,您没有犯错 - 这是使用线程的固有部分。

【讨论】:

  • 我增加了迭代的总次数,所以每个线程应该有足够的工作量,启动成本可以忽略不计。单线程执行20秒,4线程执行27秒。您在这里的解释仍然无法解释我观察到的情况。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多