Reducing Invalid Data Transfers in Non-Alignment Scenarios
[Priority] Medium
This performance optimization suggestion applies to the following models:
- Atlas 350 Accelerator Card
[Description] In non-alignment data transfer scenarios, the Atlas 350 Accelerator Card provides the DataCopyPad API at the basic API level. This API supports two transfer modes: Normal and Compact. When multiple data blocks that are not 32-byte aligned are transferred, using the Compact mode can reduce the amount of invalid data transferred, thereby saving bandwidth.
Assume that three data blocks need to be transferred, each with a size of 48 bytes and a float data type. Except for these three 48-byte data blocks, all other data is invalid.
__aicore__ inline void CopyIn(){
AscendC::LocalTensor<T> xLocal = inQueueX.AllocTensor<T>();
AscendC::Duplicate<T>(xLocal, 0, count);
AscendC::DataCopyParams dataCopyParams;
dataCopyParams.blockCount = 3;
dataCopyParams.blockLen = 48;
dataCopyParams.srcStride = 0;
dataCopyParams.dstStride = 0;
AscendC::DataCopyPadParams dataCopyPadParams;
dataCopyPadParams.isPad = 1;
dataCopyPadParams.leftPadding = 0;
dataCopyPadParams.rightPadding = 4;
dataCopyPadParams.paddingValue = 0;
AscendC::DataCopyPad<T, AscendC::PaddingMode::Normal>(xLocal, xGm, dataCopyParams, dataCopyPadParams);
inQueueX.EnQue<T>(xLocal);
}
The data in the UB after transfer is as follows:
[1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 0., 0., 0., 0., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 0., 0., 0., 0., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 0., 0., 0., 0.....]
As shown in the figure, each data block is 48 bytes and not 32-byte aligned. Therefore, 16-byte padding data needs to be inserted when each data block is transferred to achieve 32-byte alignment. Finally, 192-byte data is transferred to the UB, including 48-byte invalid data.
__aicore__ inline void CopyIn(){
AscendC::LocalTensor<T> xLocal = inQueueX.AllocTensor<T>();
AscendC::Duplicate<T>(xLocal, 0, count);
AscendC::DataCopyParams dataCopyParams;
dataCopyParams.blockCount = 3;
dataCopyParams.blockLen = 48;
dataCopyParams.srcStride = 0;
dataCopyParams.dstStride = 0;
AscendC::DataCopyPadParams dataCopyPadParams;
dataCopyPadParams.isPad = 1;
dataCopyPadParams.leftPadding = 0;
dataCopyPadParams.rightPadding = 4;
dataCopyPadParams.paddingValue = 0;
AscendC::DataCopyPad<T, AscendC::PaddingMode::Compact>(xLocal, xGm, dataCopyParams, dataCopyPadParams);
inQueueX.EnQue<T>(xLocal);
}
The data in the UB after transfer is as follows:
[1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 0., 0., 0., 0....]
According to the diagram of transfer in Compact mode, 160-byte data is finally transferred, including 16-byte invalid data.
[Summary] Through comparison, it can be found that when multiple data blocks that are not 32-byte aligned are transferred, using the Compact mode can reduce the amount of invalid data transferred, thereby saving bandwidth.