Skip to content
版 本

DataCacheCleanAndInvalid

产 品 支 持 情 况

产 品是 否 支 持(支 持 配 置dcciDst的 原 型)是 否 支 持(不 支 持 配 置dcciDst的 原 型)
Ascend 950PR/Ascend 950DT
Atlas A3 训 练 系 列 产 品/Atlas A3 推 理 系 列 产 品
Atlas A2 训 练 系 列 产 品/Atlas A2 推 理 系 列 产 品
Atlas 200I/500 A2 推 理 产 品
Atlas 推 理 系 列 产 品AI Core
x
Atlas 推 理 系 列 产 品Vector Core
xx
Atlas 训 练 系 列 产 品
xx
Kirin X90
Kirin 9030

功 能 说 明

头 文 件 路 径 为:"basic_api/kernel_operator_cache_intf.h"

如 图1所 示,在AI Core内 部,Scalar单 元 和DMA单 元 都 可 能 对GM进 行 访 问:

  • DMA搬 运 单 元 读 写GM,数 据 通 过DataCopy等 接 口 在UB等Local Memory和GM间 交 互,没 有Cache一 致 性 问 题。
  • Scalar单 元 访 问GM,首 先 会 访 问 每 个 核 内 的Data Cache,因 此 存 在Data Cache与GM的Cache一 致 性 问 题。

图 1 DataCache内 存 层 次 示 意 图

DataCacheCleanAndInvalid接 口 用 于 解 决 上 述 一 致 性 问 题,其 功 能 可 以 拆 解 为 两 部 分:

  • Clean:将 缓 存 中 被 修 改 过 的 数 据(脏 数 据,Dirty Data)写 回 到GM中,避 免 数 据 丢 失。
  • Invalid:
    • 将 指 定 地 址 范 围 的Cache Line标 记 为“无 效”,使 其 从 缓 存 中 移 除。
    • 保 证 下 一 次 访 问 这 些 内 存 地 址 时,会 从GM重 新 加 载 数 据,而 不 是 使 用 可 能 过 期 的 缓 存 数 据。

该 接 口 的 典 型 使 用 场 景 如 下:

  • 读 取GM的 数 据,但 该 数 据 可 能 在 外 部 被 其 余 核 修 改,此 时 需 要 使 用DataCacheCleanAndInvalid接 口,直 接 访 问GM,获 取 最 新 数 据。
  • 用 户 通 过Scalar单 元 写GM的 数 据,希 望 立 刻 写 出,也 需 要 使 用DataCacheCleanAndInvalid接 口。
  • 针 对Ascend 950PR/Ascend 950DT,原 子 操 作 过 程 中,如 果 希 望 改 变 后 续 数 据 的 饱 和 模 式,需 要 先 使 用DataCacheCleanAndInvalid接 口 将Cache Line中 现 存 的 数 据 立 刻 写 出,再 调 用SetCtrlSpr设 置 后 续 数 据 的 饱 和 模 式。

函 数 原 型

  • 支 持 通 过 配 置dcciDst确 保DCache与GM存 储 的 一 致 性。

    C++
    template <typename T, CacheLine entireType, DcciDst dcciDst>
    __aicore__ inline void DataCacheCleanAndInvalid(const GlobalTensor<T>& dst)
    
  • 支 持 通 过 配 置dcciDst确 保DCache与Local Memory存 储 的 一 致 性。

    C++
    template <typename T, CacheLine entireType, DcciDst dcciDst>
    __aicore__ inline void DataCacheCleanAndInvalid(const LocalTensor<T>& dst)
    
  • 不 支 持 配 置dcciDst,仅 支 持 保 证DCache与GM的 一 致 性。

    C++
    template <typename T, CacheLine entireType>
    __aicore__ inline void DataCacheCleanAndInvalid(const GlobalTensor<T>& dst)
    

参 数 说 明

表 1 模 板 参 数 说 明

参 数 名描 述
Tdst的 数 据 类 型。
entireType指 令 操 作 的 模 式:
SINGLE_CACHE_LINE:只 刷 新 传 入 地 址 所 在 的Cache Line,注 意 如 果 该 地 址 非64B对 齐,只 会 操 作 传 入 地 址 到64B对 齐 的 部 分。
ENTIRE_DATA_CACHE:此 时 传 入 的 地 址 无 效,核 内 会 刷 新 整 个DCache,但 是 耗 时 较 大,性 能 敏 感 的 场 景 慎 用
dcciDst表 示 使 用 该 接 口 来 保 证DCache与 哪 一 种 存 储 保 持 一 致 性,类 型 为DcciDst枚 举 类。
• CACHELINE_ALL:与CACHELINE_OUT效 果 一 致。
• CACHELINE_UB:表 示 通 过 该 接 口 来 保 证DCache与UB的 一 致 性。
• CACHELINE_OUT:表 示 通 过 该 接 口 来 保 证DCache与GM的 一 致 性。
• CACHELINE_ATOMIC:

 • Ascend 950PR/Ascend 950DT,原 子 操 作 过 程 中 保 证DCache和GM的 一 致 性。

 • Atlas A3 训 练 系 列 产 品/Atlas A3 推 理 系 列 产 品,暂 未 支 持。

 • Atlas A2 训 练 系 列 产 品/Atlas A2 推 理 系 列 产 品,暂 未 支 持。

 • Atlas 200I/500 A2 推 理 产 品,暂 未 支 持。

 • Atlas 推 理 系 列 产 品AI Core,暂 未 支 持。

表 2 参 数 说 明

参 数 名输 入/输 出描 述
dst输 入需 要 刷 新Cache的Tensor。

返 回 值 说 明

约 束 说 明

调 用 示 例

  • 示 例1:SINGLE_CACHE_LINE模 式(64B对 齐 场 景)
    假 设mmAddr_为0x40(64B对 齐),调 用 一 次 指 令 即 可 刷 新 整 个Cache Line。

    C++
    AscendC::GlobalTensor<uint64_t> global;
    global.SetGlobalBuffer((__gm__ uint64_t*)mmAddr_ + AscendC::GetBlockIdx() * 1024);
    for( int i = 0; i < 8; i++) {
       global.SetValue(i, AscendC::GetBlockIdx());
    }
    // 由 于 首 地 址64B对 齐,调 用DataCacheCleanAndInvalid指 令 后,会 立 刻 刷 新 前8个 数。
    AscendC::DataCacheCleanAndInvalid<uint64_t, AscendC::CacheLine::SINGLE_CACHE_LINE, AscendC::DcciDst::CACHELINE_OUT>(global);
    
  • 示 例2:SINGLE_CACHE_LINE模 式(非64B对 齐 场 景)
    假 设mmAddr_为0x20(非64B对 齐),需 要 调 用 两 次 指 令 才 能 刷 新 完 整Cache Line。

    C++
    AscendC::GlobalTensor<uint64_t> global;
    global.SetGlobalBuffer((__gm__ uint64_t*)mmAddr_ + AscendC::GetBlockIdx() * 1024);
    for( int i = 0; i < 8; i++) {
       global.SetValue(i, AscendC::GetBlockIdx());
    }
    // 由 于 首 地 址 非64B对 齐,调 用1条 指 令,只 会 刷 新 起 始 地 址 至64B字 节 对 齐 的 部 分,即 前4个 数。
    AscendC::DataCacheCleanAndInvalid<uint64_t, AscendC::CacheLine::SINGLE_CACHE_LINE, AscendC::DcciDst::CACHELINE_OUT>(global);
    // 需 要 再 次 调 用DataCacheCleanAndInvalid指 令,刷 新 后4个 数。
    AscendC::DataCacheCleanAndInvalid<uint64_t, AscendC::CacheLine::SINGLE_CACHE_LINE, AscendC::DcciDst::CACHELINE_OUT>(global[4]);
    
  • 示 例3:SINGLE_CACHE_LINE模 式(多 核 处 理 场 景)
    假 设mmAddr_为0x40(64B对 齐),多 核 操 作 同 一 条Cache Line时 可 能 出 现 随 机 覆 盖。本 样 例 仅 做 示 例 说 明,便 于 开 发 者 理 解 使 用 限 制,非 正 常 使 用 样 例。

    C++
    AscendC::GlobalTensor<uint64_t> global;
    global.SetGlobalBuffer((__gm__ uint64_t*)mmAddr_);
    global.SetValue(AscendC::GetBlockIdx(), AscendC::GetBlockIdx());
    // 算 子 中 多 核 操 作 虽 然 不 在 同 一 个 地 址,但 在 同 一 个Cache Line,会 出 现 数 据 的 随 机 覆 盖,和 通 用CPU的 行 为 不 同。
    // 调 用DataCacheCleanAndInvalid指 令 后,由 于 多 核 操 作 的 时 间 不 一 致,最 终 结 果 存 在 随 机 性,后 执 行 的 核 会 覆 盖 前 面 核 的 结 果。
    AscendC::DataCacheCleanAndInvalid<uint64_t, AscendC::CacheLine::SINGLE_CACHE_LINE, AscendC::DcciDst::CACHELINE_OUT>(global);
    
  • 示 例4:ENTIRE_DATA_CACHE模 式
    假 设mmAddr_为0x20(非64B对 齐),刷 新 整 个DCache。本 样 例 仅 做 示 例 说 明,便 于 开 发 者 理 解 使 用 限 制,非 正 常 使 用 样 例。

    C++
    AscendC::GlobalTensor<uint64_t> global;
    global.SetGlobalBuffer((__gm__ uint64_t*)mmAddr_ + AscendC::GetBlockIdx() * 1024);
    for( int i = 0; i < 8; i++) {
       global.SetValue(i, AscendC::GetBlockIdx());
    }
    // 刷 新 整 个DCache,性 能 较 差。
    AscendC::DataCacheCleanAndInvalid<uint64_t, AscendC::CacheLine::ENTIRE_DATA_CACHE, AscendC::DcciDst::CACHELINE_OUT>(global);
    

免 责 声 明:本 站 内 容 由 asc-devkit 仓 master 分 支 自 动 编 译 生 成,属 于 持 续 开 发 版 本,可 能 存 在 缺 陷,仅 供 预 览 与 参 考。如 需 稳 定 及 商 用 资 料,请 查 阅 官 方 昇 腾 社 区