昇腾950 SSBUF (Scalar Shared Buffer) 使用手册


第一章:SSBUF 概述

1.1 什么是 SSBUF

SSBUF (Scalar Shared Buffer) 是昇腾950 AI Core 中一块专用的标量共享存储区域,用于同一 AI Core 内不同管线/线程之间的轻量级数据共享参数传递

  1. 每个Core 为 1K SSBuf;
  2. 在MixCore 1:2 时,因为3个Core, 则占用3K SSBUF (地址范围: 0~3K-1; 地址空间在3个Core内可见);
  3. 在MixCore 1:1 时,不支持 SSBUF
  4. 在AivOnly, AicOnly 时,每个Core 占用1K SSBUF (地址范围: 0~1K-1)
  5. SSBUF 支持 b64 / b32 读写。 不支持 atomic 读写; 不支持 mte 读写;

1.2 SSBUF 在存储层次中的定位

存储区域 用途 访问方式 速度 共享范围
SSBUF 标量核内共享参数 LD/ST (b32/b64) 最快 (片内) 核内管线间, 读写性能 8 Cycle
UB 向量计算数据Buffer LD/ST + Vector指令 快 (片内) 核内
Stack 标量函数调用栈空间 LD/ST (所有类型) 快 (片内) 本核, 在DCache时读写性能高,当CacheMiss则为访问 GM/L2Cache
OUT (GM) 全局共享数据 LD/ST/ATOM/RED 慢 (片外) 跨核

第二章:SSBUF 访问规则

2.1 支持的指令

//SSBUF 的地址空间由用户管理, 编译器不支持分配
  __ssbuf__ int* a = 0;  
  *a = 10;      //写入, AIV0写入,AIC&AIV1 都可见。
  auto b = *a;  //读取

  struct MyStruct {   //必须32bit 对齐, 按照 32b/64b 访问
    int a;   
    int b;
    int64_t c;
    int64_t d; 
  };
  __ssbuf__ MyStruct* a = (__ssbuf__ int*)(1024);  

  __ssbuf__ int b = 0;   //不支持

  __ssbuf__ uint64_t* e = (__ssbuf__ int*)( 1024*3 - 1);
  auto v = *e; //超范围读取,异常,
   

  __ssbuf__ uint32_t* e = (__ssbuf__ int*)( 1024*3 - 4);
  auto v = *e; //64bit 地址读取, 异常

2.2 数据类型约束

数据类型 LD/ST 说明
.b32 (4B) 推荐, 标准 32bit 访问
.b64 (8B) LD/ST 支持
.b8 (1B) 触发 MPU 异常
.b16 (2B) 触发 MPU 异常

2.3 对齐约束

说明 32bit/64bit 原子操作,故AIC/AIV0/AIV1 都可见。

访问 SSBUF 的对齐要求:
  .b32: 地址必须 4B 对齐 (addr % 4 == 0)
  .b64: 地址必须 8B 对齐 (addr % 8 == 0)

违反对齐 → MEM ILLEGAL ACCESS - ADDR MISALIGN 异常

2.4 地址范围约束

见上错误描述

地址必须落在 SSBUF 区域内:
  
  SSBUF_start ≤ addr < SSBUF_end
  
  超出范围 → MEM ILLEGAL ACCESS - MPU ERROR 异常
  (由 MPU (Memory Protection Unit) 检查)

2.5 Cache 行为

SSBUF 访问不受 Cache 控制:

第三章:SSBUF 异常汇总

当访问 SSBUF 时, MPU (Memory Protection Unit) 会在以下情况报告异常:

异常场景 触发指令 条件
不支持的指令访问 SSBUF ATOM, RED, LD_DEV, ST_DEV 地址命中 SSBUF 区域
地址未对齐 LD/ST/LDP/STP/STI addr 未对齐到 4B/8B
地址越界 LD/ST/LDP/STP/STI addr 超出 SSBUF 范围
数据类型不正确 LD/ST/STI (.b8/.b16) 使用了 b8/b16 类型

第四章:SSBUF 典型使用场景

建议: SSBUF 是不兼容,在后续的版本中,会被移除; 因为SSBUF 主要是用于解决 AIC:AIV=1:2 的场景;

4.1 场景一:AIC生产, AIV0/AIV1消费的共享数据

4.2 场景二:常量初始化,或者Tiling

//本样例采用2个AIV 把 Tiling 搬运到SSBUF, 提升搬运效率
  //  鉴定Tiling的长度为 256 * 4 字节;
  //  GetSubBlockIdx() AIV0返回0; AIV1 返回1

  __ubuf__  int a[256];                        //a 的地址由编译时分配
  __ssbuf__ int* b = AscendC::GetSubBlockIdx() * 1K;   //b 的地址编译器不分配, 由程序员分配

  CopyGm2UB(a, gmAddr + AscendC::GetSubBlockIdx() * 1K , sizeof(a));

  //在mixCore 内 subBlockIDx =0, 则执行写 ssbuf 
  
  for(int i=0; i<256; i++) {
    *(b++) = a[i];
  }
  //aiv0/aiv1 通知 aic, 数据搬运完成
  AscendC::CrossCoreSetFlag<2, PIPE_S>(0);  //AIV 通知AIC 
  AscendC::CrossCoreWaitFlag<2, PIPE_S>(0); //等待 AIC-SetCross, 这样就完
Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐