gpt4 book ai didi

c++ - 在 C++ 中使用 SIMD vector 进行矩阵乘法

转载 作者:行者123 更新时间:2023-12-02 10:13:25 27 4
gpt4 key购买 nike

我目前正在 github 上阅读一篇关于使用 Clang 的扩展 vector 语法进行性能优化的文章。作者给出以下代码片段:

The templated code below implements the innermost loops that calculate a patch of size regA x regB in matrix C. The code loads regA scalars from matrixA and regB SIMD-width vectors from matrix B. The program uses Clang's extended vector syntax.

/// 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

最佳答案

文章第二条评论链接到https://github.com/pytorch/glow/blob/405e632ef138f1d49db9c3181182f7efd837bccc/lib/Backends/CPU/libjit/libjit_defs.h#L26它定义了 float8键入为

typedef float float8 __attribute__((ext_vector_type(8)));
(类似于 immintrin.h 定义 __m256 的方式)。并定义了加载/广播函数类似于 _mm256_load_ps_mm256_set1_ps .使用该 header ,您应该能够编译文章中的代码。
Clang's native vector documentation . GNU C native vector 语法是获得重载 * 的好方法。运算符(operator)。不知道是什么clang的 ext_vector_type GCC/clang/ICC float __attribute__((vector_width(32))) (32 字节宽度)不会。
这篇文章本来可以增加 1 小节来解释这一点,但似乎更侧重于性能细节,并且对解释如何使用语法并不真正感兴趣。
文章中的大部分讨论都是关于如何使用 SIMD vector 手动向量化 matmul 以提高缓存效率。从我给它的快速浏览来看,这部分看起来不错。
您可以使用多种手动 vector 方法中的任何一种来执行这些操作:GNU C native vector 或 clang 非常相似的“扩展” vector ,或可移植的 Intel 内在函数。

关于c++ - 在 C++ 中使用 SIMD vector 进行矩阵乘法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62729814/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com