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

编译器自动修复工具

未使用编译器自动修复工具

  1. (可选)下载GCC源码(请从GCC官网下载对应版本的源码)。本实践使用的是GCC 9.3.0源码包,编译并设置GCC环境变量,如图1所示。
    图1 设置GCC环境变量

    具体编译过程,请参见GCC官网相关文档。

  2. 根据以下流程使用已安装的GCC 9.3.0,执行20000次源码包编译生成可执行文件测试,如图 复现内存一致性问题所示。
    1. 解压源码包并确认文件内容。
      tar -zxvf fifo.tar.gz
      ls
    2. 编译源码。
      make
    3. 运行生成的可执行文件。
      ./one_producer_one_consumer

    源码中是一个单生产者单消费者的无锁队列,其中生产者会依次向栈中推入1,2,3三个int类型数据,消费者会读取栈中数据并向r1,r2,r3三个int类型变量赋值,在没有内存一致性错误发生时,预期结果应为r1=1,r2=2,r3=3。

    图2 复现内存一致性问题

    执行结果:20000次测试中,复现内存一致性问题共计12次。

使用编译器自动修复工具

  1. 安装内存一致性修复组件。
    1. 获取内存一致性修复组件。

      内存一致性修复组件: 从DevKit安装路径下,找到 “/opt/DevKit/devkitplugins/affinity/tools/weakconsistency/gccchecker/gcctool.tar.gz”

      “/opt/DevKit”为工具安装目录,请根据实际情况替换。

    2. 执行以下命令,解压安装包。
      tar xf gcctool.tar.gz

      解压后确认“gcctool/bin”目录下有以下文件:gcctool,gcctool-bin,libstdc++.so.6

    3. 配置环境变量。

      将“gcctool”放入自定义目录,配置环境变量:export PATH=/path/to/gcctool/bin:$PATH

      其中,“/path/to”为gcctool存放的自定义目录。

  2. 下载GCC源码并解压(请从GCC官网下载对应版本的源码),本实践使用的是GCC 9.3源码包。

    GCC修复工具 patch:https://github.com/kunpengcompute/devkitdriver/tree/main/gccchecker(Debian系列和Redhat系列操作系统都使用该依赖包。)

    tar -xvf gcc-9.3.0.tar.gz
  3. 执行以下命令,合入GCC patch,如图3所示。
    cd gcc-9.3.0/
    patch -p1 < /path/to/gcc-9.3.0.patch
    图3 合入GCC 9.3 patch
  4. 编译GCC,设置GCC环境变量,如图4所示。
    • 具体编译过程,请参见GCC官网相关文档。
    • 配置环境变量路径以实际编译安装路径为准。
    图4 设置环境变量
  5. 编译fifo源码。

    进入fifo源码目录,设置内存一致性修复组件优化等级“export HW_DEBUG=[ 0 | 1 | 2 ]”。当前实践内容设置组件优化等级为1,执行make命令进行编译。

    export HW_DEBUG=1
    make clean
    make
    编译完成后再执行以下命令。
    objdump -d one_producer_one_consumer | grep dmb | head -20

    即可显示20个自动修复的位置,如图5所示。

    编译组件支持通过环境变量配置修复优化等级,不设置环境变量,修复工具不会生效。

    图5 修复工具生效

    export HW_DEBUG=[ 0 | 1 | 2 ]

    • 0:不使用优化策略,性能损失最大。
    • 1:使用最安全的修复策略,性能损失较大。
    • 2:应用组件优化规则,可以减少性能损失。
  6. 验证源码修复效果。
    在源码目录执行以下指令:
    ./one_producer_one_consumer

    连续执行可执行文件中的测试,执行20000次未出现内存一致性问题,编译器自动修复工具生效,如图6所示。

    图6 自动修复工具生效

编译器自动修复工具验证结论

fifo源码在未使用修复工具时,共执行了20000次测试,其中12次执行异常。使用修复工具后,插入了20000个内存屏障指令,继续执行20000次测试,没有出现异常现象。