在没有 sudo 权限的机器上分析与 OpenMP 并行的 C++ 程序的最简单方法是什么?
1 回答
我建议使用英特尔 VTune Amplifier XE 分析器。
基本热点分析不需要 root 权限,您甚至可以在不使用 sudoers 的情况下安装它。
对于 OpenMP 分析,最好在运行配置文件会话之前使用英特尔 OpenMP 实现进行编译并将环境变量 KMP_FORKJOIN_FRAMES 设置为 1。这将使该工具能够可视化每个平行区域从分叉点到连接点的时间区域。这很好地说明了哪里有足够的并行性,哪里没有。通过使用像帧域/帧类型/函数这样的网格分组,您还可以将并行区域与 CPU 上发生的事情相关联,从而可以找到无法扩展的函数。
例如,想象一个像下面这样的简单代码,它运行一些平衡的工作,然后是一些串行的工作,然后是一些不平衡的工作,为所有这些调用 delay() 函数,确保 delay() 不会内联。这模仿了一个真实的工作负载,其中可能从并行区域调用各种不熟悉的函数,这使得仅通过查看热函数配置文件来分析并行性是好还是坏变得更加困难:
void __attribute__ ((noinline)) balanced_work() {
printf("Starting ideal parallel\n");
#pragma omp parallel
delay(3000000);
}
void __attribute__ ((noinline)) serial_work() {
printf("Starting serial work\n");
delay(3000000);
}
void __attribute__ ((noinline)) imbalanced_work() {
printf("Starting parallel with imbalance\n");
#pragma omp parallel
{
int mythread = omp_get_thread_num();
int nthreads = omp_get_num_threads();
delay(1000000);
printf("First barrier %d\n", mythread);
#pragma omp barrier
delay(mythread * 25000 + 200000);
printf("Second barrier %d\n", mythread);
#pragma omp barrier
delay((nthreads - 1 - mythread) * 25000 + 200000);
printf("Join barrier %d\n", mythread);
}
}
int
main(int argc, char **argv)
{
setvbuf(stdout, NULL, _IONBF, 0);
calibrate();
balanced_work();
serial_work();
imbalanced_work();
printf("Bye bye\n");
}
对于此代码,典型的函数配置文件将显示在 delay() 函数中花费的大部分时间。另一方面,在 VTune 中查看带有帧分组和 CPU 使用信息的数据,可以了解什么是串行的,什么是不平衡的,什么是平衡的。以下是您在 VTune 中可能看到的内容:
在这里可以看到:
- 当我们执行一个不平衡的区域时,有 13.671 的经过时间。从 CPU 使用率细分可以看出不平衡。
- 有 3.652 的经过时间非常平衡。这里有一些红色时间,这可能是一些系统影响 - 值得在实际案例中进行调查。
- 然后我也有大约 4 秒的串行时间。确定它是 4 秒目前有点棘手 - 您必须从摘要中获取经过的时间(在我的情况下为 21.276)并从中减去 13.671 和 3.652 得出四。但很容易。
希望这可以帮助。