在 macOS Apple Silicon 上使用 Homebrew 的 Clang 编译的 C++ 代码在使用 OpenMP 的情况下运行速度明显慢于不使用 OpenMP 的情况

2023-12-20

我正在尝试在 Apple Silicon (Apple M1 Max) 上的 macOS Monterey (12.5.1) 上编译支持 OpenMP 的 C++ 代码,以获得相应的加速。

该代码计算量大,易于理解,多年来一直使用 OpenMP(例如在 x64 Ubuntu 上),没有出现任何问题;计算或多或少是令人尴尬的并行,因此通过 OpenMP 以多线程方式运行计算的速度是显着的。

当我使用 Apple Clang 在 macOS 上编译代码时,一切正常,除了代码当然是单线程运行的,因为 AppleClang 不支持 OpenMP。

这就是为什么我现在使用 Homebrew 的 Clang 编译所有内容以启用 OpenMP。不幸的是,结果与预期不同。代码编译并使用OpenMP;我发现因为我必须解决一些小问题firstprivateClang 比 GCC 更严格的子句,我看到使用多个线程执行。

然而,运行时withOpenMP 是明显慢一些 than withoutOpenMP。例如,不使用 OpenMP 的计算需要大约 15 秒,使用 OpenMP 需要大约 90 秒,即使在最糟糕的扩展情况下,我预计速度会提高 2 倍到 4 倍。否则计算结果是正确的,它似乎只是影响速度。

我尝试使用 llvm 14(稳定 14.0.6(瓶装))和 llvm 13(稳定 13.0.1(瓶装),由于怀疑回归而尝试)编译该软件,但到目前为止没有成功。

该项目正在使用 CMake,配置如下所示(这是使用 LLVM 13,但我事先尝试过使用默认的 llvm):

export PATH="/opt/homebrew/opt/llvm@13/bin:$PATH"
...
cmake ../../ -DCMAKE_BUILD_TYPE=Release  \
  -DCMAKE_PREFIX_PATH=/opt/homebrew/opt/llvm@13   \
  -DCMAKE_CXX_COMPILER=/opt/homebrew/opt/llvm@13/bin/clang++   \
  -DCMAKE_C_COMPILER=/opt/homebrew/opt/llvm@13/bin/clang   \
  -DLDFLAGS="-L/opt/homebrew/opt/llvm@13/lib"   \
  -DCPPFLAGS="-I/opt/homebrew/opt/llvm@13/include"

我很高兴就如何解决此问题提供任何建议。提前致谢!

--

更新1:

当 OMP_DISPLAY_ENV 启用时,将显示以下内容:

OPENMP DISPLAY ENVIRONMENT BEGIN
   _OPENMP='201611'
  [host] OMP_AFFINITY_FORMAT='OMP: pid %P tid %i thread %n bound to OS proc set {%A}'
  [host] OMP_ALLOCATOR='omp_default_mem_alloc'
  [host] OMP_CANCELLATION='FALSE'
  [host] OMP_DEFAULT_DEVICE='0'
  [host] OMP_DISPLAY_AFFINITY='FALSE'
  [host] OMP_DISPLAY_ENV='TRUE'
  [host] OMP_DYNAMIC='FALSE'
  [host] OMP_MAX_ACTIVE_LEVELS='1'
  [host] OMP_MAX_TASK_PRIORITY='0'
  [host] OMP_NESTED: deprecated; max-active-levels-var=1
  [host] OMP_NUM_TEAMS='0'
  [host] OMP_NUM_THREADS: value is not defined
  [host] OMP_PROC_BIND='false'
  [host] OMP_SCHEDULE='static'
  [host] OMP_STACKSIZE='8176k'
  [host] OMP_TARGET_OFFLOAD=DEFAULT
  [host] OMP_TEAMS_THREAD_LIMIT='0'
  [host] OMP_THREAD_LIMIT='2147483647'
  [host] OMP_TOOL='enabled'
  [host] OMP_TOOL_LIBRARIES: value is not defined
  [host] OMP_TOOL_VERBOSE_INIT: value is not defined
  [host] OMP_WAIT_POLICY='PASSIVE'
OPENMP DISPLAY ENVIRONMENT END

一旦我将 OMP_NUM_THREADS 设置为特定数字,我的测试用例就会产生以下运行时间(通过 Boost 的 cpu_timer 获得的时间)。我们可以清楚地看到,代码在单线程(通过 OMP_NUM_THREADS=1 设置)上运行时速度最快,即使它是使用 OpenMP 支持进行编译的。

  • OMP_NUM_THREADS=1:15.85s wall, 30.97s user + 0.56s system = 31.53s CPU (198.9%)
  • OMP_NUM_THREADS=2:28.91s wall, 69.93s user + 0.71s system = 70.64s CPU (244.3%)
  • OMP_NUM_THREADS=4:36.63s wall, 134.07s user + 1.47s system = 135.54s CPU (370.0%)
  • OMP_NUM_THREADS=8:52.18s wall, 267.80s user + 12.35s system = 280.15s CPU (536.9%)
  • OMP_NUM_THREADS=10:52.29s wall, 285.78s user + 10.57s system = 296.35s CPU (566.8%)

更新2:

来自 asitop 的系统负载 (https://github.com/tlkh/asitop https://github.com/tlkh/asitop):

OMP_NUM_THREADS=1 OMP_NUM_THREADS=8
System load from asitop when OMP_NUM_THREADS=1 System load from asitop when OMP_NUM_THREADS=8

None

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

在 macOS Apple Silicon 上使用 Homebrew 的 Clang 编译的 C++ 代码在使用 OpenMP 的情况下运行速度明显慢于不使用 OpenMP 的情况 的相关文章

  • 如何检查图像对象与资源中的图像对象是否相同?

    所以我试图创建一个简单的程序 只需在单击图片框中更改图片即可 我目前只使用两张图片 所以我的图片框单击事件函数的代码 看起来像这样 private void pictureBox1 Click object sender EventArgs
  • Qt-Qlist 检查包含自定义类

    有没有办法覆盖加载自定义类的 Qt QList 的比较机制 即在 java 中你只需要重写一个比较方法 我有一个带有我的自定义类模型的 QList QList
  • pthread_cond_timedwait() 和 pthread_cond_broadcast() 解释

    因此 我在堆栈溢出和其他资源上进行了大量搜索 但我无法理解有关上述函数的一些内容 具体来说 1 当pthread cond timedwait 因为定时器值用完而返回时 它如何自动重新获取互斥锁 互斥锁可能被锁定在其他地方 例如 在生产者
  • UML类图:抽象方法和属性是这样写的吗?

    当我第一次为一个小型 C 项目创建 uml 类图时 我在属性方面遇到了一些麻烦 最后我只是将属性添加为变量 lt
  • C#:如何防止主窗体过早显示

    在我的 main 方法中 我像往常一样启动主窗体 Application EnableVisualStyles Application SetCompatibleTextRenderingDefault false Application
  • 将目录压缩为单个文件的方法有哪些

    不知道怎么问 所以我会解释一下情况 我需要存储一些压缩文件 最初的想法是创建一个文件夹并存储所需数量的压缩文件 并创建一个文件来保存有关每个压缩文件的数据 但是 我不被允许创建许多文件 只能有一个 我决定创建一个压缩文件 其中包含有关进一步
  • Qt moc 在头文件中实现?

    是否可以告诉 Qt MOC 我想声明该类并在单个文件中实现它 而不是将它们拆分为 h 和 cpp 文件 如果要在 cpp 文件中声明并实现 QObject 子类 则必须手动包含 moc 文件 例如 文件main cpp struct Sub
  • 从路径中获取文件夹名称

    我有一些路c server folderName1 another name something another folder 我如何从那里提取最后一个文件夹名称 我尝试了几件事 但没有成功 我只是不想寻找最后的 然后就去休息了 Thank
  • Github Action 在运行可执行文件时卡住

    我正在尝试设置运行google tests on a C repository using Github Actions正在运行的Windows Latest 构建过程完成 但是当运行测试时 它被卡住并且不执行从生成的可执行文件Visual
  • for循环中计数器变量的范围是多少?

    我在 Visual Studio 2008 中收到以下错误 Error 1 A local variable named i cannot be declared in this scope because it would give a
  • 如何将单个 char 转换为 int [重复]

    这个问题在这里已经有答案了 我有一串数字 例如 123456789 我需要提取它们中的每一个以在计算中使用它们 我当然可以通过索引访问每个字符 但是如何将其转换为 int 我研究过 atoi 但它需要一个字符串作为参数 因此 我必须将每个字
  • Discord.net 无法在 Linux 上运行

    我正在尝试让在 Linux VPS 上运行的 Discord net 中编码的不和谐机器人 我通过单声道运行 但我不断收到此错误 Unhandled Exception System Exception Connection lost at
  • 将 unsigned char * (uint8_t *) 转换为 const char *

    我有一个带有 uint8 t 参数的函数 uint8 t ihex decode uint8 t in size t len uint8 t out uint8 t i hn ln for i 0 i lt len i 2 hn in i
  • 需要哪个版本的 Visual C++ 运行时库?

    microsoft 的最新 vcredist 2010 版 是否包含以前的版本 2008 SP1 和 2005 SP1 还是我需要安装全部 3 个版本 谢谢 你需要所有这些
  • 将文本叠加在图像背景上并转换为 PDF

    使用 NET 我想以编程方式创建一个 PDF 它仅包含一个背景图像 其上有两个具有不同字体和位置的标签 我已阅读过有关现有 PDF 库的信息 但不知道 如果适用 哪一个对于如此简单的任务来说最简单 有人愿意指导我吗 P D 我不想使用生成的
  • 在 Dynamics CRM 插件中访问电子邮件发件人地址

    我正在编写一个 Dynamics CRM 2011 插件 该插件挂钩到电子邮件实体的更新后事件 阶段 40 pipeline http msdn microsoft com en us library gg327941 aspx 并且在此阶
  • 为什么 C# Math.Ceiling 向下舍入?

    我今天过得很艰难 但有些事情不太对劲 在我的 C 代码中 我有这样的内容 Math Ceiling decimal this TotalRecordCount this PageSize Where int TotalRecordCount
  • x86 上未对齐的指针

    有人可以提供一个示例 将指针从一种类型转换为另一种类型由于未对齐而失败吗 在评论中这个答案 https stackoverflow com questions 544928 reading integer size bytes from a
  • 如何在 C++ BOOST 中像图形一样加载 TIFF 图像

    我想要加载一个 tiff 图像 带有带有浮点值的像素的 GEOTIFF 例如 boost C 中的图形 我是 C 的新手 我的目标是使用从源 A 到目标 B 的双向 Dijkstra 来获得更高的性能 Boost GIL load tiif
  • 防止索引超出范围错误

    我想编写对某些条件的检查 而不必使用 try catch 并且我想避免出现 Index Out of Range 错误的可能性 if array Element 0 Object Length gt 0 array Element 1 Ob

随机推荐