核心隔离将 OpenMP 限制为单个核心

问题描述 投票:0回答:1

在调查代码的性能问题后,我意识到在“隔离核心”上运行的基于 OpenMP 的并行代码将线程数限制为单个核心。 此代码应将 for 循环展开到 N 个核心(例如

$OMP_NUM_THREADS=N

):

// g++ -fopenmp -I/usr/include/ -03 test_openmp.cpp -o testomp
#include <immintrin.h>
#include <cmath>
#include <chrono>
#include <iostream>
const float nano = 1000000000;
int main(){
    std::size_t niter = 10000000000;
    auto start = std::chrono::system_clock::now();
    #pragma omp parallel for
    for(std::size_t i = 0; i < niter; i++){
        std::size_t x = sqrt(i);
    }
    auto elapsed = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now() - start);
    std::cout << "Took " << elapsed.count()/nano << " s" << std::endl;
}

在我的开发系统上,有 32 个核心; 0-15 是孤立的,而 16-31 不是孤立的。
在隔离的核心上运行代码给出:

OMP_NUM_THREADS=4 taskset -c 0-3 ./testomp Took 5.33671 s

在非隔离核心上

OMP_NUM_THREADS=4 taskset -c 16-19 ./testomp Took 1.33193 s

此外,
htop

显示隔离 CPU 测试中 1 个 100% 利用率的核心,而非隔离 CPU 测试显示 4 个 CPU 核心 100% 利用率。

有没有办法允许 OpenMP 在并行 for 循环中使用多个隔离内核?出于性能原因(避免内核任务等),使用隔离内核至关重要。

如果不是,OpenMP 如何区分隔离核和非隔离核?

编辑

我使用

-0 3

启用了优化。当然,执行时间会减少,但这不是重点(也不是基准测试)。关键是代码运行在多个非隔离内核上,但只运行在一个隔离内核上。但是,在隔离核心上,我看到有四个线程正在运行。

我正在使用 GNU C++ 编译器:

~$ g++ --version g++ (Ubuntu 9.4.0-1ubuntu1~20.04.2) 9.4.0

OpenMP版本是4.5

CPU及其配置:

~$ lscpu lscpu Architecture: x86_64 CPU op-mode(s): 32-bit, 64-bit Byte Order: Little Endian Address sizes: 52 bits physical, 57 bits virtual CPU(s): 128 On-line CPU(s) list: 0-63 Off-line CPU(s) list: 64-127 Thread(s) per core: 1 Core(s) per socket: 32 Socket(s): 2 NUMA node(s): 2 Vendor ID: AuthenticAMD CPU family: 25 Model: 17 Model name: AMD EPYC 9354 32-Core Processor Stepping: 1 Frequency boost: enabled CPU MHz: 1499.458 CPU max MHz: 3799.0720 CPU min MHz: 1500.0000 BogoMIPS: 6499.69 Virtualization: AMD-V L1d cache: 2 MiB L1i cache: 2 MiB L2 cache: 64 MiB L3 cache: 512 MiB NUMA node0 CPU(s): 0-31


c++ parallel-processing openmp
1个回答
1
投票

查看

cpuset 手册页

,我们看到

CPUsets 与 sched_setaffinity(2) 调度集成 亲和力机制以及 mbind(2) 和 set_mempolicy(2) 内存- 内核中的放置机制。这些机制都没有 让进程使用不存在的 CPU 或内存节点 该进程的 cpuset 允许。如果改变一个进程的 cpuset 放置与这些其他机制冲突,那么 即使这意味着覆盖这些,也会强制执行 cpuset 放置 其他机制。

因此明确表示 cpuset 实现旨在阻止代码转义,但这似乎正是您想要的。

因此我认为这与OpenMP没有太大关系,它只是遵守其运行的Linux系统的规则。

© www.soinside.com 2019 - 2024. All rights reserved.