【发布时间】:2020-10-25 00:40:59
【问题描述】:
我目前正在 github 上阅读一篇关于使用 Clang 的扩展向量语法进行性能优化的文章。作者给出如下代码sn-p:
下面的模板化代码实现了计算矩阵 C 中大小为 regA x regB 的补丁的最内层循环。代码从矩阵 A 加载 regA 标量,从矩阵 B 加载 regB SIMD 宽度向量。程序使用 Clang 的扩展向量语法。
/// Compute a RAxRB block of C using a vectorized dot product, where RA is the
/// number of registers to load from matrix A, and RB is the number of registers
/// to load from matrix B.
template <unsigned regsA, unsigned regsB>
void matmul_dot_inner(int k, const float *a, int lda, const float *b, int ldb,
float *c, int ldc) {
float8 csum[regsA][regsB] = {{0.0}};
for (int p = 0; p < k; p++) {
// Perform the DOT product.
for (int bi = 0; bi < regsB; bi++) {
float8 bb = LoadFloat8(&B(p, bi * 8));
for (int ai = 0; ai < regsA; ai++) {
float8 aa = BroadcastFloat8(A(ai, p));
csum[ai][bi] += aa * bb;
}
}
}
// Accumulate the results into C.
for (int ai = 0; ai < regsA; ai++) {
for (int bi = 0; bi < regsB; bi++) {
AdduFloat8(&C(ai, bi * 8), csum[ai][bi]);
}
}
}
下面概述的代码最让我困惑。我读了整篇文章,理解了使用阻塞和计算小补丁背后的逻辑,但我不能完全理解这个位是什么意思:
// Perform the DOT product.
for (int bi = 0; bi < regsB; bi++) {
float8 bb = LoadFloat8(&B(p, bi * 8)); //the pointer to the range of values?
for (int ai = 0; ai < regsA; ai++) {
float8 aa = BroadcastFloat8(A(ai, p));
csum[ai][bi] += aa * bb;
}
}
}
谁能详细说明这里发生了什么? 文章可以找到here
【问题讨论】:
标签: c++ clang matrix-multiplication simd