Visual Studio下多线程OMP C++程序性能分析问题排查
我正在Visual Studio 2017中分析一个重度多线程C++程序。任务管理器显示程序将所有CPU核心和线程的使用率维持在100%,但性能分析器显示仅约33%的时间消耗在我的代码中,约60%的时间消耗在KernelBase.dll中。我的代码并未进行任何内核调用,因此我想知道这60%的时间是否因上下文切换丢失,或是在OMP应用中使用分析器导致的结果。我计划编写一个极简多线程应用测试是否会出现类似结果,同时想了解是否存在其他需要注意的因素?
编辑1
加载所有内核符号后发现问题出在NtYieldExecution上。我曾搜索过相关问题但暂无有效回复,会进一步查找信息。

编辑2
尝试将OMP_WAIT_TIME设置为ACTIVE和PASSIVE:
ACTIVE模式下得到最初的高CPU占用但低效的结果;PASSIVE模式下消除了所有NtYieldExecution调用,但所有线程的总CPU使用率最高仅约35%(ACTIVE模式下为100%,大部分时间浪费在让出周期上)。

长时间测试显示,PASSIVE模式耗时60.3秒,ACTIVE模式耗时71.8秒。这表明微软的OMP实现对于我使用的线程粒度而言效率不高,需要考虑其他替代方案。
编辑3
测试多种调度组合和块大小后,在OMP_WAIT_TIME=PASSIVE且使用如下代码时得到了稍好的结果,CPU使用率约60%:
#pragma omp for schedule(dynamic, 64)
我已尝试了static、dynamic、guided调度策略,以及空值、16、64、256、1024等块大小,覆盖OMP_WAIT_TIME=PASSIVE和ACTIVE两种模式。原本期望块大小能带来更显著的提升,但实际最优与最差结果的差异仅约20%,且OMP_WAIT_TIME=PASSIVE模式稍快,同时CPU总使用率更低(推测功耗也更低)。

编辑4
使用Visual Studio 2022 17.5.318重新编译后,性能下降了10%。尝试启用和禁用/openmp:llvm选项,但未产生明显差异。
内容的提问来源于stack exchange,提问作者SmacL

