---
title: 代码插桩分析法
description: "由于编译器、数学库和硬件上的差异，在鲲鹏平台和x86平台运行结果是不一致的。面对两者的差异，下面的介绍的方法可以准确地找到产生差异的代码，进而分析出原因。"
url: https://www.hikunpeng.com/document/detail/zh/perftuning/computp-wp/kunpengcomputp_19_0017.html
sourcePath: /source/zh/perftuning/computp-wp/kunpengcomputp_19_0017.html
indexId: 448a7cd551e91ea4486d2b7e48e6f75ccd89c52ad7c5c67fb3e19635bcd337a860
---
# 代码插桩分析法

由于编译器、数学库和硬件上的差异，在鲲鹏平台和x86平台运行结果是不一致的。面对两者的差异，下面的介绍的方法可以准确地找到产生差异的代码，进而分析出原因。

下面以WRF 3.4.1代码进行举例，在分析差异前，需要明确鲲鹏和x86机器上使用的编译器、编译选项和软件栈，保证鲲鹏和x86使用同一WRF版本和同一算例。

图1 插桩分析法流程

插桩思路为：假定在两个平台上函数的输入是一致的，若函数内部的计算不会产生差异，则两个平台上函数输出是一致的。反之，函数内部必然存在产生差异的代码。

找到代码的主要计算路径，如WRF 3.4.1中的solve_em.F，该模块对气象要素进行大量的计算，影响最终的结果生成。对solve_em.F中的所有函数作为目标函数进行插桩分析。

1. 为满足假定的条件（即函数输入一致），可通过读写文件操作实现。例如：

  a. 在x86平台上，调用set_tiles前插入write_args函数，将set_tiles的输入值写入文件。

```
! x86调用write_args将输入值写入文件
CALL write_args(grid, ids, ide, jds, jde, ips, ipe, jps, jpe)
CALL set_tiles(grid, ids, ide, jds, jde, ips, ipe, jps, jpe)
```


  b. x86写文件完成后将其拷贝到鲲鹏平台，在鲲鹏平台上同样的代码位置插入函数read_args读取x86上的参数值。

```
! 鲲鹏调用read_args读取文件值并赋值给输入
CALL read_args(grid, ids, ide, jds, jde, ips, ipe, jps, jpe)
CALL set_tiles(grid, ids, ide, jds, jde, ips, ipe, jps, jpe)
```


2. 对比两个平台的输出，考虑到函数输出可能是一个极大的数组，直接对比具体的值不直观，可以通过计算输出的MD5值进行对比。可在set_tiles后调用print_md5函数进行输出值的MD5计算和打印。

  - x86平台代码如下：

```
! x86调用write_args将参数值写入文件
CALL write_args(grid, ids, ide, jds, jde, ips, ipe, jps, jpe)
CALL set_tiles(grid, ids, ide, jds, jde, ips, ipe, jps, jpe)
! x86打印输出MD5值
CALL print_md5(grid, ids, ide, jds, jde, ips, ipe, jps, jpe)
```


  - 鲲鹏平台代码如下：

```
! 鲲鹏调用read_args读取文件值并赋值给参数
CALL read_args(grid, ids, ide, jds, jde, ips, ipe, jps, jpe)
CALL set_tiles(grid, ids, ide, jds, jde, ips, ipe, jps, jpe)
! 鲲鹏打印输出MD5值
CALL print_md5(grid, ids, ide, jds, jde, ips, ipe, jps, jpe)
```


3. 对比set_tiles函数输出值MD5结果，可以看出两个平台输出是完全一致的，可以断定set_tiles不会导致结果差异。

  - 鲲鹏中set_tiles函数输出MD5值打印结果：
    1 2 3 4 5 6 7 8 ids md5sum is :4352d88a78aa39750bf70cd6f27bcaa5 ide md5sum is :78cf7f2f5161bd0bb9fd139e10624c07 jds md5sum is :4352d88a78aa39750bf70cd6f27bcaa5 jde md5sum is :78cf7f2f5161bd0bb9fd139e10624c07 ips md5sum is :4352d88a78aa39750bf70cd6f27bcaa5 ipe md5sum is :b15762fc4c227bbdb97385765fb475f4 jps md5sum is :4352d88a78aa39750bf70cd6f27bcaa5 jpe md5sum is :d2f2de0f320b64a33cdefe91e8632b54

  - x86中set_tiles函数输出MD5值打印结果：
    1 2 3 4 5 6 7 8 ids md5sum is :4352d88a78aa39750bf70cd6f27bcaa5 ide md5sum is :78cf7f2f5161bd0bb9fd139e10624c07 jds md5sum is :4352d88a78aa39750bf70cd6f27bcaa5 jde md5sum is :78cf7f2f5161bd0bb9fd139e10624c07 ips md5sum is :4352d88a78aa39750bf70cd6f27bcaa5 ipe md5sum is :b15762fc4c227bbdb97385765fb475f4 jps md5sum is :4352d88a78aa39750bf70cd6f27bcaa5 jpe md5sum is :d2f2de0f320b64a33cdefe91e8632b54

4. solve_em.F中还调用calc_p_rho_phi函数，用同样的方法来分析calc_p_rho_phi函数，其输出值MD5打印结果：

  - 鲲鹏中calc_p_rho_phi函数输出MD5值打印结果：
    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 moist md5sum is :6b67192bd614cbcd0e46ed5d607479a0 num_3d_m md5sum is :7303f017fe369f9ce5af630da93ba867 config_flags%hypsometric_opt md5sum is :4352d88a78aa39750bf70cd6f27bcaa5 grid%al md5sum is :db28d22d61ccf7aaef53151c08bad13e grid%alb md5sum is :7df859bac212ad24233f0e35c347b79c grid%mu_2 md5sum is :78da02688276d78aebd7198ffea21ef6 grid%muts md5sum is :dbcaf66d2fb30baafbfab7f075e1325e grid%ph_2 md5sum is :9d5ab368e3398baa8b6eabf310e06515 grid%phb md5sum is :357f65254210d7544455ac35ee9b87b7 grid%p md5sum is :a9d0a0bd98710620b70c8e0b82b8cdf9 grid%pb md5sum is :7b44de932f45be71671722478a4b0c87 grid%t_2 md5sum is :f3d260a80c699900c6294ea356f0d64c p0 md5sum is :a6c5b219b5715388be8ac391f95602ab t0 md5sum is :2b37b3fa8052b64b82a21602e662e4ca grid%p_top md5sum is :96a8a83edaccefc72356a9a64a5484ac grid%znu md5sum is :65337863d0f5ad50c2492ba81f22d7bd grid%znw md5sum is :16b3ab5e2ec5e92d312a055b46ce4cc5 grid%dnw md5sum is :04fdee143ffda95f156e872762efbb17 grid%rdnw md5sum is :f838011b20bb121e63737fde1fd5dd3f grid%rdn md5sum is :a00dba2a5675a1a5ea4b85e97257e1bd config_flags%non_hydrostatic md5sum is :a54f0041a9e15b050f25c463f1db7449

  - x86中calc_p_rho_phi函数输出MD5值打印结果：
    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 moist md5sum is :6b67192bd614cbcd0e46ed5d607479a0 num_3d_m md5sum is :7303f017fe369f9ce5af630da93ba867 config_flags%hypsometric_opt md5sum is :4352d88a78aa39750bf70cd6f27bcaa5 grid%al md5sum is :db28d22d61ccf7aaef53151c08bad13e grid%alb md5sum is :7df859bac212ad24233f0e35c347b79c grid%mu_2 md5sum is :78da02688276d78aebd7198ffea21ef6 grid%muts md5sum is :dbcaf66d2fb30baafbfab7f075e1325e grid%ph_2 md5sum is :9d5ab368e3398baa8b6eabf310e06515 grid%phb md5sum is :357f65254210d7544455ac35ee9b87b7 grid%p md5sum is :5e0897900e4534f9ad7d70ce616d2954 grid%pb md5sum is :7b44de932f45be71671722478a4b0c87 grid%t_2 md5sum is :f3d260a80c699900c6294ea356f0d64c p0 md5sum is :a6c5b219b5715388be8ac391f95602ab t0 md5sum is :2b37b3fa8052b64b82a21602e662e4ca grid%p_top md5sum is :96a8a83edaccefc72356a9a64a5484ac grid%znu md5sum is :65337863d0f5ad50c2492ba81f22d7bd grid%znw md5sum is :16b3ab5e2ec5e92d312a055b46ce4cc5 grid%dnw md5sum is :04fdee143ffda95f156e872762efbb17 grid%rdnw md5sum is :f838011b20bb121e63737fde1fd5dd3f grid%rdn md5sum is :a00dba2a5675a1a5ea4b85e97257e1bd config_flags%non_hydrostatic md5sum is :a54f0041a9e15b050f25c463f1db7449


从两个平台的输出对比可以看出calc_p_rho_phi函数的输出grid%p是不一致的。接下来用同样的插桩思路对calc_p_rho_phi函数中涉及grid%p变量的函数进行插桩分析，最终定位到其调用了vpow函数导致grid%p变量不一致。

图2 vpow代码片段

vpow函数只是做pow运算，跟程序调用的数学库有关。在鲲鹏平台上替换成KML数学库后calc_p_rho_phi函数的输出值与x86保持一致。

遍历所有目标函数，使用插桩方法即可对WRF软件完成结果差异分析。
