Ana*_*nas 0 c++ multithreading fortran openmp
我有一个多线程应用程序,可以并行解决巨大的矩阵。我最近更换了笔记本电脑,并开始在新笔记本电脑上出现一些奇怪的行为。旧笔记本电脑中的处理器是第 11 代英特尔(R) 酷睿(TM) i9-11950H,新笔记本电脑中的处理器是第 12 代英特尔(R) 酷睿(TM) i9-12900H。在旧笔记本电脑上运行我的多线程应用程序(使用 4 个线程)时,我看到这些线程占用了 4 个核心并充分利用它们,由于笔记本电脑有 8 个物理核心,总体 CPU 使用率约为 50%。请看下图:
当使用相同(完全相同)的可执行二进制文件运行相同的应用程序时,我发现只有一个核心得到充分利用,其余核心的利用率约为 10%-20%,总体 CPU 使用率低于 15%。请看下图:
有没有解释为什么相同的二进制文件在一台机器上运行而没有在另一台机器上运行?
笔记:
注意:在配备第 12 代英特尔(R) 酷睿(TM) i9-12900H 的笔记本电脑上,我从 BIOS 禁用了 E 核心,以确保线程仅分配给 P 核心,但这并没有解决问题。请看下面:
从上图中我们可以看到,只有线程1充分利用了它的CPU。
以下是我启动线程的方式:
CALL OMP_SET_NUM_THREADS(4)
!$OMP PARALLEL DO PRIVATE(i)
DO i = 1, 4, 1
CALL solve_axb_r_submat(n, A, line_A, X, B, flag, i, submatrix_number, Fkluunit(i))
END DO
!$OMP END PARALLEL DO
Run Code Online (Sandbox Code Playgroud)
上面的代码被调用超过 20000 次,因此每次迭代都会调用一个具有上面代码段的函数。我正在使用 Visual studio 2022 和 OpeApi 2023 在 Windows 上工作。以下是我的一些项目属性:
请注意我们添加的命令行以确定上一个图像中线程的关联性。当我们添加时,我们看到线程被固定在同一个核心上,并且不在核心之间移动。
i9-11950H 处理器是 Tiger-Lake 处理器,而 i9-12900H 是 Alder-Lake 处理器。主要区别在于 Alder-Lake 具有 Big-Little 架构,而前者是统一的(并且更加主流)。实际上,这意味着有两组核心:大核心速度快但能量效率低,小核心能量效率高但速度慢。这种架构在笔记本电脑上非常有趣,因此可以在性能和功耗之间提供良好的权衡。在某些特定情况下,高效的内核还可以帮助提高 CPU 的整体性能。坏消息是,迄今为止,许多运行时和应用程序对这种架构的支持很差。一个主要问题是不同类型的核心导致的负载不平衡。事实上,对于相同的工作负载,在性能核心上运行的 1 个线程通常比在高效核心上运行的线程运行得更快。较快的线程应等待其他线程,因此整体计算受到较慢核心的限制。我想这就是这里发生的情况:1 个核心被密集使用,而其他 3 个核心几乎没有使用,其他核心则处于空闲状态。我的假设是,密集使用的核心是高效核心,而其他核心是性能核心(等待慢速核心)。
您可以请求 OpenMP 使用动态调度,以便自动平衡不同内核之间的工作负载。这会产生额外的开销,但在这种情况下可能会更好。schedule(dynamic)
一种方法是在并行 for 循环上使用子句。另一种方法是调整环境变量OMP_SCHEDULE
。
或者,您可以自行绑定 OpenMP 线程,以便使用相同类型的内核。您可以通过更改环境变量来做到这一点OMP_PROC_BIND
,OMP_PLACES
这应该是操作系统应该自动执行的操作,但看起来它失败了(或者这实际上不是问题)...
归档时间: |
|
查看次数: |
946 次 |
最近记录: |