OpenMP 开销计算

2023-12-03

给定 n 个线程,有没有一种方法可以计算在 OpenMP 中实现特定指令所需的开销量(例如周期数)。

例如,给出下面的代码

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

我可以以某种方式计算创建这些线程需要多少开销吗?


我认为衡量开销的方法是对串行和并行版本进行计时,然后查看并行版本与线程数的“理想”运行时间相差多远。

例如,如果您的串行版本需要 10 秒,并且您在 4 个内核上有 4 个线程,那么您的理想运行时间是 2.5 秒。如果您的 OpenMP 版本需要 4 秒,那么您的“开销”就是 1.5 秒。我将开销放在引号中,因为其中一些将是线程创建和内存共享(实际的线程开销),而其中一些将只是未并行的代码部分。我试图在这里思考阿姆达尔定律.

为了演示,这里有两个例子。它们不测量线程创建开销,但可能显示预期改进和实现改进之间的差异。虽然神秘主义是正确的,唯一真正的衡量方法是计时,但即使是像你这样的微不足道的例子for循环不一定受内存限制。 OpenMP 做了很多我们看不到的工作。

串行(速度测试.cpp)

#include <iostream>

int main(int argc, char** argv) {
  const int SIZE = 100000000;
  int* a = new int[SIZE];
  int* b = new int[SIZE];
  int* c = new int[SIZE];

  for(int i = 0; i < SIZE; i++) {
    a[i] = b[i] * c[i] * 2;
  }

  std::cout << "a[" << (SIZE-1) << "]=" << a[SIZE-1] << std::endl;

  for(int i = 0; i < SIZE; i++) {
    a[i] = b[i] + c[i] + 1;
  }

  std::cout << "a[" << (SIZE-1) << "]=" << a[SIZE-1] << std::endl;

  delete[] a;
  delete[] b;
  delete[] c;

  return 0;
}

并行(omp_speedtest.cpp)

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

int main(int argc, char** argv) {
  const int SIZE = 100000000;
  int* a = new int[SIZE];
  int* b = new int[SIZE];
  int* c = new int[SIZE];

  std::cout << "There are " << omp_get_num_procs() << " procs." << std::endl;

  #pragma omp parallel
  {
    #pragma omp for
    for(int i = 0; i < SIZE; i++) {
      a[i] = b[i] * c[i];
    }
  }

  std::cout << "a[" << (SIZE-1) << "]=" << a[SIZE-1] << std::endl;

  #pragma omp parallel
  {
    #pragma omp for
    for(int i = 0; i < SIZE; i++) {
      a[i] = b[i] + c[i] + 1;
    }
  }

  std::cout << "a[" << (SIZE-1) << "]=" << a[SIZE-1] << std::endl;

  delete[] a;
  delete[] b;
  delete[] c;

  return 0;
}

所以我用这些来编译这些

g++ -O3 -o speedtest.exe speedtest.cpp
g++ -fopenmp -O3 -o omp_speedtest.exe omp_speedtest.cpp

当我运行它们时

$ time ./speedtest.exe
a[99999999]=0
a[99999999]=1

real    0m1.379s
user    0m0.015s
sys     0m0.000s

$ time ./omp_speedtest.exe
There are 4 procs.
a[99999999]=0
a[99999999]=1

real    0m0.854s
user    0m0.015s
sys     0m0.015s
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

OpenMP 开销计算 的相关文章

  • 未提供参数时如何指定 C# System.Commandline 行为?

    在我的控制台应用程序中 当未提供控制台参数时 将执行我指定列表 在本例中为参数 3 的任何处理程序 调用该处理程序时 布尔参数设置为 false 但对我来说 根本不调用它更有意义 如何防止这种情况发生并显示帮助文本 using System
  • Directory.Delete 之后 Directory.Exists 有时返回 true ?

    我有非常奇怪的行为 我有 Directory Delete tempFolder true if Directory Exists tempFolder 有时 Directory Exists 返回 true 为什么 可能是资源管理器打开了
  • 确保 StreamReader 不会挂起等待数据

    下面的代码读取从 tcp 客户端流读取的所有内容 并且在下一次迭代中它将仅位于 Read 上 我假设正在等待数据 我如何确保它不会在没有任何内容可供读取时返回 我是否必须设置低超时 并在失败时响应异常 或者有更好的办法吗 TcpClient
  • 使用 LINQ2SQL 在 ASP.NET MVC 中的各种模型存储库之间共享数据上下文

    我的应用程序中有 2 个存储库 每个存储库都有自己的数据上下文对象 最终结果是我尝试将从一个存储库检索到的对象附加到从另一个存储库检索到的对象 这会导致异常 Use 构造函数注入将 DataContext 注入每个存储库 public cl
  • 复制目录内容

    我想将目录 tmp1 的内容复制到另一个目录 tmp2 tmp1 可能包含文件和其他目录 我想使用C C 复制tmp1的内容 包括模式 如果 tmp1 包含目录树 我想递归复制它们 最简单的解决方案是什么 我找到了一个解决方案来打开目录并读
  • 使用 Newtonsoft 和 C# 反序列化嵌套 JSON

    我正在尝试解析来自 Rest API 的 Json 响应 我可以获得很好的响应并创建了一些类模型 我正在使用 Newtonsoft 的 Json Net 我的响应中不断收到空值 并且不确定我的模型设置是否正确或缺少某些内容 例如 我想要获取
  • java.io.Serialized 在 C/C++ 中的等价物是什么?

    C C 的等价物是什么java io Serialized https docs oracle com javase 7 docs api java io Serializable html 有对序列化库的引用 用 C 序列化数据结构 ht
  • 在 C 中初始化变量

    我知道有时如果你不初始化int 如果打印整数 您将得到一个随机数 但将所有内容初始化为零似乎有点愚蠢 我问这个问题是因为我正在评论我的 C 项目 而且我对缩进非常直接 并且它可以完全编译 90 90 谢谢 Stackoverflow 但我想
  • 在 Visual Studio 2010 中从 Fortran 调用 C++ 函数

    我想从 Fortran 调用 C 函数 为此 我在 Visual Studio 2010 中创建了一个 FORTRAN 项目 之后 我将一个 Cpp 项目添加到该 FORTRAN 项目中 当我要构建程序时出现以下错误 Error 1 unr
  • 我可以使用 moq Mock 来模拟类而不是接口吗?

    正在经历https github com Moq moq4 wiki Quickstart https github com Moq moq4 wiki Quickstart 我看到它 Mock 一个接口 我的遗留代码中有一个没有接口的类
  • C#:帮助理解 UML 类图中的 <>

    我目前正在做一个项目 我们必须从 UML 图编写代码 我了解 UML 类图的剖析 但我无法理解什么 lt
  • Azure 辅助角色“请求输入之一超出范围”的内部异常。

    我在辅助角色中调用 CloudTableClient CreateTableIfNotExist 方法 但收到一个异常 其中包含 请求输入之一超出范围 的内部异常 我做了一些研究 发现这是由于将表命名为非法表名引起的 但是 我尝试为我的表命
  • 等待进程释放文件

    我如何等待文件空闲以便ss Save 可以用新的覆盖它吗 如果我紧密地运行两次 左右 我会得到一个generic GDI error
  • 使用 C# 读取 Soap 消息

  • 如果没有抽象成员,基类是否应该标记为抽象?

    如果一个类没有抽象成员 可以将其标记为抽象吗 即使没有实际理由直接实例化它 除了单元测试 是的 将不应该实例化的基类显式标记为抽象是合理且有益的 即使在没有抽象方法的情况下也是如此 它强制执行通用准则来使非叶类抽象 它阻止其他程序员创建该类
  • 如何部署“SQL Server Express + EF”应用程序

    这是我第一次部署使用 SQL Server Express 数据库的应用程序 我首先使用实体 框架模型来联系数据库 我使用 Install Shield 创建了一个安装向导来安装应用程序 这些是我在目标计算机中安装应用程序所执行的步骤 安装
  • 无法接收 UDP Windows RT

    我正在为 Windows 8 RT 编写一个 Windows Store Metro Modern RT 应用程序 需要在端口 49030 上接收 UDP 数据包 但我似乎无法接收任何数据包 我已按照使用教程进行操作DatagramSock
  • Oracle Data Provider for .NET 不支持 Oracle 19.0.48.0.0

    我们刚刚升级到 Oracle 19c 19 3 0 所有应用程序都停止工作并出现以下错误消息 Oracle Data Provider for NET 不支持 Oracle 19 0 48 0 0 我将 Oracle ManagedData
  • 如何从 ODBC 连接获取可用表的列表?

    在 Excel 中 我可以转到 数据 gt 导入外部数据 gt 导入数据 然后选择要使用的数据源 然后在提供登录信息后 它会给我一个表格列表 我想知道如何使用 C 以编程方式获取该列表 您正在查询什么类型的数据源 SQL 服务器 使用权 看
  • 从列表中选择项目以求和

    我有一个包含数值的项目列表 我需要使用这些项目求和 我需要你的帮助来构建这样的算法 下面是一个用 C 编写的示例 描述了我的问题 int sum 21 List

随机推荐