我正在尝试在 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;我发现因为我必须解决一些小问题firstprivate
Clang 比 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 |
|
|