---
title: 调优简介
description: "MPI_Allreduce函数会对数组进行规约操作（sum += a1+a2+a3…），高并发场景下，规约的顺序会极大影响浮点计算结果。精度问题本质上是并行领域长期存在的可复制性（Reproducibility）问题，其根本原因在于计算机浮点计算有截断误差，不满足结合律，如图1。由于计算结果依赖于操作的顺序，当有多进程/多线程进行运算时，必然会因为计算顺序不同而导致差异的存在。"
url: https://www.hikunpeng.com/document/detail/zh/perftuning/precisionopt/kunpengprecision_12_0022.html
sourcePath: /source/zh/perftuning/precisionopt/kunpengprecision_12_0022.html
indexId: a52a4f3771bf52d2d3109ac7255b2a360daf26d89e3b44655619b0f745e8205e64
---
# 调优简介

MPI_Allreduce函数会对数组进行规约操作（sum += a1+a2+a3…），高并发场景下，规约的顺序会极大影响浮点计算结果。精度问题本质上是并行领域长期存在的可复制性（Reproducibility）问题，其根本原因在于计算机浮点计算有截断误差，不满足结合律，如图1。由于计算结果依赖于操作的顺序，当有多进程/多线程进行运算时，必然会因为计算顺序不同而导致差异的存在。

图1 结合律问题

MPI中涉及依赖于操作顺序的浮点计算的操作有MPI_Allreduce、MPI_Reduce、MPI_Reduce_scatter、MPI_Scan和MPI_Exscan。MPI集合通信操作有很多不同的集合通信算法。不同的算法，规约顺序不同，最终计算结果也不尽相同，以Allreduce Algorithm为例（Recursive Doubling对比Rabenseifner）：


- 在MPI集合通信操作中即使算法名称相同，其实现方式也有差异。以Allreduce Algorithm为例：Rabenseifner算法由scatter+allgather两个phase组成，每个phase可以采取不同的算法组合。所以即使名称一样，算法的实现也会不同。


图2 Rabenseifner（recursive having对比ring）的数据流图


- 即使是相同的MPI集合通信算法，每次运行计算结果也可能会有不同。

  - 对于tree算法，reduce过程是many-to-one过程，这就导致到达顺序不可控。
  - 当parent采用先收集所有child数据再归约，性能差，但是结果一致。
  - 当parent采用先到先归约的方式，会有归约顺序的问题，性能好，但是结果不一致。
    图3 K项树逻辑图（K-nomial tree）

- 在不同平台上，计算结果也不同。

  - 非拓扑感知算法，规约顺序始终是固定的。
  - 拓扑感知算法，每次会节点内进程先汇聚到node leader，如果不同机器的核数不同，结果会有差异。
高并发场景是指：在同时或极短时间内，有大量的MPI进程请求规约。
