中文
注册
我要评分
文档获取效率
文档正确性
内容完整性
文档易理解
在线提单
论坛求助

CPU使用率过低导致应用执行阻塞

现象

应用运行时,如果环境变量OMP_NUM_THREADS设置线程数过低,或omp_set_num_threads函数设置线程数过低,会导致CPU资源未充分利用,后续应用执行时间增加。

调优思路

使用鲲鹏DevKit系统性能分析执行HPC应用分析任务,定位分析应用对资源的使用情况。进一步分析源码,调整参数,充分利用服务器资源,缩短应用运行时长。

操作步骤

  1. 准备示例源码omp_utilization.c并进行编译。
    gcc omp_utilization.c -O3 -o omp_utilization -fopenmp -lm
  2. 使用鲲鹏DevKit系统性能分析执行HPC应用分析任务。
    表1 任务配置参数说明

    参数

    说明

    分析对象

    应用

    应用路径

    输入程序所在的绝对路径,例如本示例将代码样例放在服务器“/opt/testdemo/omp_utilization”路径下。

    分析类型

    HPC应用分析

    采集模式

    OpenMP模式;本示例主要是对OMP的应用进行分析。

    分析模式

    统计分析

    采样模式

    Summary模式

    采样时长

    默认

  3. 查看任务结果。

    观察到CPU使用率较低,OpenMP Team使用率指标中执行应用使用了47个线程,但CPU存在128个核,此时OMP线程数远小于CPU核数,未充分利用CPU核数,运行时长为17.68秒。

    示例中环境变量OMP_NUM_THREADS设置为128。

    图1 分析结果
  4. 对源码进行分析。
    源码中omp_set_num_threads函数设置的线程数为48,服务器实际核数为128核,未充分利用CPU资源。
    void OmpUtilBench(Point *pointA, Point *pointB, double *pointDis, int n)
    {
        assert(pointA != NULL && pointB != NULL && pointDis != NULL);
        int i;
        omp_set_num_threads(48);
        #pragma omp parallel for shared (n) private (i)
        for (i = 0; i < n; i++) {
            pointDis[i] = ComputPointDistance(&pointA[i], &pointB[i]);
        }
    }
  5. 优化配置。

    删除omp_set_num_threads函数调用,同时取消服务器上OMP_NUM_THREADS环境变量。

    void OmpUtilBench(Point *pointA, Point *pointB, double *pointDis, int n)
    {
        assert(pointA != NULL && pointB != NULL && pointDis != NULL);
        int i;
        #pragma omp parallel for shared (n) private (i)
        for (i = 0; i < n; i++) {
            pointDis[i] = ComputPointDistance(&pointA[i], &pointB[i]);
        }
    }
    unset OMP_NUM_THREADS
  6. 将修改后的源码再次编译
    gcc omp_utilization.c -O3 -o omp_utilization -fopenmp -lm
  7. 再次执行HPC应用分析。

优化效果

优化后应用使用96个线程,较之前的47个已有提升,运行时长缩短为13.08秒。

图2 优化后分析结果