c++ - 分析 OpenMP 并行化 C++ 代码

标签 c++ parallel-processing profiling openmp

在没有 sudo 权限的机器上分析与 OpenMP 并行的 C++ 程序的最简单方法是什么?

最佳答案

我建议使用英特尔 VTune Amplifier XE 分析器。

Basic Hotspots 分析不需要 root 权限,您甚至可以在不使用 sudoers 的情况下安装它。

对于 OpenMP 分析,最好使用英特尔 OpenMP 实现进行编译,并在运行配置文件 session 之前将环境变量 KMP_FORKJOIN_FRAMES 设置为 1。这将使该工具能够可视化每个并行区域从 fork 点到连接点的时间区域。这很好地了解了哪些地方有足够的并行性,哪些地方没有。通过使用像帧域/帧类型/函数这样的网格分组,您还可以将并行区域与 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 内容:

OpenMP frames for the sample

从这里可以看出:

  • 当我们执行不平衡区域时,耗时为 13.671。从 CPU 使用率 segmentation 可以看出这种不平衡。
  • 有 3.652 的耗时非常平衡。这里有一些红色时间,这可能是一些系统效应 - 值得在真实案例中进行调查。
  • 然后我还有大约 4 秒的连续时间。弄清楚它是 4 秒目前有点棘手 - 你必须从摘要中获取耗时(在我的例子中是 21.276)并从中减去 13.671 和 3.652 得到 4。但是很容易。

希望这对您有所帮助。

关于c++ - 分析 OpenMP 并行化 C++ 代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17382402/

相关文章:

c - 线程中的 OpenMP 阻塞调用

javascript - jQuery 1.3 与 1.4(性能)

tensorflow - 通过 Tensorflow 利用多个 CPU 内核

java - 一个函数如何变成原子的?

weblogic - 如何以分析模式启动WebLogic?

c - 在 C 代码中回归运行时相关降级的最佳方法

c++ - 摆脱有符号和无符号整数表达式之间比较的优雅方法

c++ - 在 C++11 中,按值传递是一个合理的默认值吗?

只能用作 constexpr 变量的 C++ 类型

c++ - 在 C++ 中将 double* 转换为 int*