---
title: 异步场景处理
description: "Matmul的Iterate(https://www.hiascend.comdocument/detail/zh/canncommercial/900/API/ascendcopapi/atlasascendc_api_07_0638.html)和IterateAll(https://www.hiascend.comdocument/detail/zh/canncommercial/900/API/ascendcopapi/atlasascendc_api_07_0640.html)接口在MIX场景（包含矩阵计算和矢量计算）下提供了同步和异步两种模式，纯Cube场景（只有矩阵计算）下，只支持同步模式。"
url: https://www.hiascend.com/document/detail/zh/canncommercial/latest/programug/Ascendcopdevg/atlas_ascendc_10_10015.html
sourcePath: /source/zh/canncommercial/900/programug/Ascendcopdevg/atlas_ascendc_10_10015.html
indexId: 13ff75c4506e35bb3330d185068e464515f5847a320a49c15ea7ea51e982ae7581
---
# 异步场景处理

#### 功能介绍

Matmul的Iterate(https://www.hiascend.comdocument/detail/zh/canncommercial/900/API/ascendcopapi/atlasascendc_api_07_0638.html)和IterateAll(https://www.hiascend.comdocument/detail/zh/canncommercial/900/API/ascendcopapi/atlasascendc_api_07_0640.html)接口在MIX场景（包含矩阵计算和矢量计算）下提供了同步和异步两种模式，纯Cube场景（只有矩阵计算）下，只支持同步模式。

同步模式指的是程序执行时，需要等待某个操作完成后才能继续执行下一步操作。 异步模式指的是程序执行时，不需要等待某个操作完成就可以继续执行下一步操作。

- Iterate&GetTensorC的同步和异步

  - 同步：执行完一次Iterate迭代计算后，执行    GetTensorC(https://www.hiascend.comdocument/detail/zh/canncommercial/900/API/ascendcopapi/atlasascendc_api_07_0639.html)
搬运矩阵C分片，搬运完成后，才能进行下一次计算。如下图所示，C矩阵中，矩阵块1搬走后，才能计算矩阵块2，矩阵块2搬运完成后，才能计算矩阵块3。
    Iterate&GetTensorC同步模式的关键代码示例如下：

    1 2 3 while (mm.Iterate()) { mm.GetTensorC(gm_c); }

  - 异步：通过设置Iterate接口的模板参数开启异步模式。调用Iterate后，无需立即调用GetTensorC同步等待矩阵C分块搬运完成，可以先执行其它操作，待需要获取结果时再调用GetTensorC。异步模式可以减少同步等待，提高并行度，开发者对计算性能要求较高时，可以选用该方式。异步场景时，需要使用一块临时空间来缓存Iterate计算结果，否则会覆盖计算结果，调用GetTensorC时会在该临时空间中获取C的矩阵分片。临时空间通过    SetWorkspace(https://www.hiascend.comdocument/detail/zh/canncommercial/900/API/ascendcopapi/atlasascendc_api_07_0654.html)
接口进行设置。SetWorkspace接口需要在Iterate接口之前调用。
    Iterate&GetTensorC异步模式的关键代码示例如下： 1 2 3 4 5 6 7 8 9 mm.SetWorkspace(workspace, size); // 其中，workspace为临时空间的物理地址，size为singleCoreM * singleCoreN的矩阵C大小 // 异步模式 mm.template Iterate<false>(); …… // 执行其他操作 auto mIter = Ceil(singleCoreM, baseM); auto nIter = Ceil(singleCoreN, baseN); for (int i = 0; i < mIter * nIter ; ++i) { mm.GetTensorC<false> (gm_c); }

- IterateAll的同步和异步

  - 同步：后续操作需要同步等待IterateAll执行结束。
    IterateAll同步模式的关键代码示例如下：

    1 2 3 4 5 6 mm.SetTensorA(gm_a); // 设置左矩阵A mm.SetTensorB(gm_b); // 设置右矩阵B mm.SetBias(gm_bias); // 设置Bias mm.IterateAll(gm_c); // 后续操作 ...

  - 异步：后续操作不需要同步等待IterateAll执行结束，需要IterateAll的结果时，调用    WaitIterateAll(https://www.hiascend.comdocument/detail/zh/canncommercial/900/API/ascendcopapi/atlasascendc_api_07_0641.html)
等待IterateAll异步接口返回。
    IterateAll异步模式的关键代码示例如下： 1 2 3 4 5 6 7 8 9 AscendC::Matmul<aType, bType, cType, biasType> mm; mm.SetTensorA(queryGm[tensorACoreOffset]); mm.SetTensorB(keyGm[tensorBCoreOffset + sInnerStart * singleProcessSInnerSize * tilingData->attentionScoreOffsetStrideParams.matmulHead], true); mm.SetTail(singleProcessSOuterSize, mmNNum); mm.template IterateAll<false>(workspaceGm[tmp_block_idx * mmResUbSize * sInnerLoopTimes],0, false,true); // 执行其他操作 mm.WaitIterateAll(); // 等待IterateAll完成 DataCopy(dstUB, GM); // 进行GM到UB的拷贝


#### 使用场景

- Iterate&GetTensorC的同步：MIX场景（包含矩阵计算和矢量计算）、纯Cube场景（只有矩阵计算）。
- Iterate&GetTensorC的异步：仅MIX场景（包含矩阵计算和矢量计算）。
- IterateAll的同步：MIX场景（包含矩阵计算和矢量计算）、纯Cube场景（只有矩阵计算）。
- IterateAll的异步：仅MIX场景（包含矩阵计算和矢量计算）。


#### 约束说明

- Iterate&GetTensorC的异步场景：

  - 传入的C矩阵地址空间大小需要保证不小于baseM * baseN。
  - SetWorkspace接口需要在Iterate接口之前调用。
  - 支持只输出到VECIN、只输出到Global Memory，同时输出到Global Memory和VECIN三种输出方式。
  - 取出C矩阵到VECIN时，数据格式仅支持NZ；取出C矩阵到GM时，数据格式支持ND或NZ。
- IterateAll的异步场景：

  - 传入的C矩阵地址空间大小需要保证不小于singleCoreM * singleCoreN。
  - 仅支持连续输出至Global Memory。


#### 调用示例

- Iterate&GetTensorC的异步场景的完整样例请参考异步场景样例(https://gitcode.com/cann/asc-devkit/tree/9.0.0/examples/01_simd_cpp_api/03_libraries/00_matrix/matmul_leaky_relu_async)、Iterate异步场景样例(https://gitcode.com/cann/asc-devkit/tree/9.0.0/examples/01_simd_cpp_api/03_libraries/00_matrix/matmul_async_iterate)。
- IterateAll的异步场景的完整样例请参考IterateAll异步场景样例(https://gitcode.com/cann/asc-devkit/tree/9.0.0/examples/01_simd_cpp_api/03_libraries/00_matrix/matmul_async_iterate_all)。
