关于vector 访问Unified Buffer的request问题
收藏回复举报
关于vector 访问Unified Buffer的request问题
t('forum.solved') 已解决
发表于2025-12-22 16:31:18
0 查看

我在使用mindstudio分析我算子性能的时候,有一个不理解的现象。我的测试代码如下:

/**
 * @file add_custom.cpp
 *
 * Copyright (C) 2025. Huawei Technologies Co., Ltd. All rights reserved.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 */
#include "kernel_operator.h"

class KernelAdd {
public:
    __aicore__ inline KernelAdd() {}
    __aicore__ inline void Init(GM_ADDR x, GM_ADDR z)
    {
        xGm.SetGlobalBuffer((__gm__ float *)x , 65536 / sizeof(float));
        zGm.SetGlobalBuffer((__gm__ float *)z , 48 * 65536 / sizeof(float));

    }
    __aicore__ inline void Process()
    {
            Compute();
    }

private:

    __aicore__ inline void Compute()
    {

        AscendC::LocalTensor<float> xLocalPing(AscendC::TPosition::VECIN, xPingAddr, 65536/sizeof(float));
        AscendC::LocalTensor<float> xLocalPong(AscendC::TPosition::VECIN, xPongAddr, 65536/sizeof(float));
        AscendC::LocalTensor<float> zLocal(AscendC::TPosition::VECOUT, zAddr, 65536/sizeof(float));

        AscendC::DataCopy(xLocalPing, xGm, 65536/sizeof(float));
        AscendC::SetFlag<AscendC::HardEvent::MTE2_V>(EVENT_ID0);
        AscendC::WaitFlag<AscendC::HardEvent::MTE2_V>(EVENT_ID0);

        AscendC::DataCopy(xLocalPong, xGm, 65536/sizeof(float));
        AscendC::SetFlag<AscendC::HardEvent::MTE2_V>(EVENT_ID1);
        AscendC::WaitFlag<AscendC::HardEvent::MTE2_V>(EVENT_ID1);

        uint64_t mask = 64;
        AscendC::Mul(zLocal[0], xLocalPing[0], xLocalPong[0], mask, 128, { 1, 1, 1, 8, 8, 8 });
        // AscendC::Mul(zLocal[0], xLocalPing[0], xLocalPong[64], mask, 128, { 1, 1, 1, 8, 8, 8 });

        AscendC::DataCopy(zGm[AscendC::GetBlockIdx()* 65536 / sizeof(float)], zLocal, 65536 / sizeof(float));

    }
    static constexpr uint32_t xPingAddr = 0;
    static constexpr uint32_t xPongAddr = 65536; // 64kB
    static constexpr uint32_t zAddr = 131072;    // 128kB

    AscendC::GlobalTensor<float> xGm;
    AscendC::GlobalTensor<float> zGm;
    uint32_t blockLength;
    uint32_t tileNum;
    uint32_t tileLength;
};


extern "C" __global__ __aicore__ void add_custom(GM_ADDR x, GM_ADDR z)
{
    KernelAdd op;
    op.Init(x, z);
    op.Process();
}

具体的,我想测试AscendC::Mul函数的执行过程中,vector对于UB的实际访存量。然后我发现以下两种运行方式得到的vector read ub的request的结果是不一致的。

对于第一种执行方式:

AscendC::Mul(zLocal[0], xLocalPing[0], xLocalPong[0], mask, 128, { 1, 1, 1, 8, 8, 8 });

mindstudio的结果显示,Vector Write UB是128个Requests。Vector Read UB是256个Requests。

对于第二种执行方式:

AscendC::Mul(zLocal[0], xLocalPing[0], xLocalPong[64], mask, 128, { 1, 1, 1, 8, 8, 8 });

mindstudio的结果显示,Vector Write UB是128个Requests。Vector Read UB是128个Requests。

对于这2种方式,xLocalPing的地址初始化都是0,xLocalPong的地址初始化都是是65536。

我能够理解第1种执行方式的结果,因为AscendC::Mul的repeat的次数是128,参数mask是64,所以每次repeat完成64个float的加法,所以每次repeat要访问64*sizeof(float)*2=512Byte的数据。所以总的Vector Read UB的数据量大小就是128*512Byte。如果假设每次Request的大小是256Byte的话,Vector Read UB的Request的数目就是256。理论结果和实验结果一致。

但是对于第2种执行方式,我的AscendC::Mul的参数是一致的,mask是64,repeat是128。唯一不同的是xLocalPong的起始地址是xLocalPong[64]。但是计算量和访存量和第一种方式都是一样的,为什么Vector Read UB的Request的数目是128。只有第一种方式的一半了?

我的机器是昇腾800T A2训练产品,芯片是昇腾910B,cann版本是8.3.rc1,驱动是25.3.rc1,OS是ubuntu22.04。以下是我的编译命令和编译脚本:

RUN_WITH_TOOLCHAIN=1 bash run.sh -r npu -v Ascend910B2


 

#!/bin/bash
CURRENT_DIR=$(
    cd $(dirname ${BASH_SOURCE:-$0})
    pwd
)
cd $CURRENT_DIR

BUILD_TYPE="Debug"
INSTALL_PREFIX="${CURRENT_DIR}/out"

SHORT=r:,v:,i:,b:,p:,
LONG=run-mode:,soc-version:,install-path:,build-type:,install-prefix:,
OPTS=$(getopt -a --options $SHORT --longoptions $LONG -- "$@")
eval set -- "$OPTS"
SOC_VERSION="Ascend310P3"

while :; do
    case "$1" in
    -r | --run-mode)
        RUN_MODE="$2"
        shift 2
        ;;
    -v | --soc-version)
        SOC_VERSION="$2"
        shift 2
        ;;
    -i | --install-path)
        ASCEND_INSTALL_PATH="$2"
        shift 2
        ;;
    -b | --build-type)
        BUILD_TYPE="$2"
        shift 2
        ;;
    -p | --install-prefix)
        INSTALL_PREFIX="$2"
        shift 2
        ;;
    --)
        shift
        break
        ;;
    *)
        echo "[ERROR]: Unexpected option: $1"
        break
        ;;
    esac
done

RUN_MODE_LIST="cpu sim npu"
if [[ " $RUN_MODE_LIST " != *" $RUN_MODE "* ]]; then
    echo "[ERROR]: RUN_MODE error, This sample only support specify cpu, sim or npu!"
    exit -1
fi

VERSION_LIST="Ascend910A Ascend910B Ascend310B1 Ascend310B2 Ascend310B3 Ascend310B4 Ascend310P1 Ascend310P3 Ascend910B1 Ascend910B2 Ascend910B3 Ascend910B4"
if [[ " $VERSION_LIST " != *" $SOC_VERSION "* ]]; then
    echo "[ERROR]: SOC_VERSION should be in [$VERSION_LIST]"
    exit -1
fi

if [ -n "$ASCEND_INSTALL_PATH" ]; then
    _ASCEND_INSTALL_PATH=$ASCEND_INSTALL_PATH
elif [ -n "$ASCEND_HOME_PATH" ]; then
    _ASCEND_INSTALL_PATH=$ASCEND_HOME_PATH
else
    if [ -d "$HOME/Ascend/ascend-toolkit/latest" ]; then
        _ASCEND_INSTALL_PATH=$HOME/Ascend/ascend-toolkit/latest
    else
        _ASCEND_INSTALL_PATH=/usr/local/Ascend/ascend-toolkit/latest
    fi
fi

export ASCEND_TOOLKIT_HOME=${_ASCEND_INSTALL_PATH}
export ASCEND_HOME_PATH=${_ASCEND_INSTALL_PATH}
echo "[INFO]: Current compile soc version is ${SOC_VERSION}"
source ${_ASCEND_INSTALL_PATH}/bin/setenv.bash
if [ "${RUN_MODE}" = "sim" ]; then
    # in case of running op in simulator, use stub .so instead
    export LD_LIBRARY_PATH=${_ASCEND_INSTALL_PATH}/tools/simulator/${SOC_VERSION}/lib:$LD_LIBRARY_PATH
elif [ "${RUN_MODE}" = "cpu" ]; then
    export LD_LIBRARY_PATH=${_ASCEND_INSTALL_PATH}/tools/tikicpulib/lib:${_ASCEND_INSTALL_PATH}/tools/tikicpulib/lib/${SOC_VERSION}:${_ASCEND_INSTALL_PATH}/tools/simulator/${SOC_VERSION}/lib:$LD_LIBRARY_PATH
fi

set -e
rm -rf build out
mkdir -p build
cmake -B build \
    -DRUN_MODE=${RUN_MODE} \
    -DSOC_VERSION=${SOC_VERSION} \
    -DCMAKE_BUILD_TYPE=${BUILD_TYPE} \
    -DCMAKE_INSTALL_PREFIX=${INSTALL_PREFIX} \
    -DASCEND_CANN_PACKAGE_PATH=${_ASCEND_INSTALL_PATH}
cmake --build build -j
cmake --install build

rm -f ascendc_kernels_bbit
cp ./out/bin/ascendc_kernels_bbit ./
rm -rf input output
mkdir -p input output
(
    export LD_LIBRARY_PATH=$(pwd)/out/lib:$(pwd)/out/lib64:${_ASCEND_INSTALL_PATH}/lib64:$LD_LIBRARY_PATH
    if [[ "$RUN_WITH_TOOLCHAIN" -eq 1 ]]; then
        if [ "${RUN_MODE}" = "npu" ]; then
            msprof op --aic-metrics=Roofline --application=./ascendc_kernels_bbit
        elif [ "${RUN_MODE}" = "sim" ]; then
            msprof op simulator --soc-version=Ascend910B2 --application=./ascendc_kernels_bbit
        elif [ "${RUN_MODE}" = "cpu" ]; then
            ./ascendc_kernels_bbit
        fi
    else
        ./ascendc_kernels_bbit
    fi
)
# tidy folder by delete log files
if [ "${RUN_MODE}" = "sim" ]; then
    rm -f *.log *.dump *.vcd *.toml *_log
fi
md5sum output/*.bin

我要发帖子