首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >C++中基于SIMD向量的矩阵乘法

C++中基于SIMD向量的矩阵乘法
EN

Stack Overflow用户
提问于 2020-07-04 13:36:03
回答 1查看 1.7K关注 0票数 1

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

下面的模板代码实现了计算矩阵C中大小为regA x regB的补丁的最内部循环。代码从matrixA加载regA标量,从矩阵B加载regB SIMD宽度向量。程序使用Clang的扩展向量语法。

代码语言:javascript
运行
复制
/// 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]);
    }
  }
}

下面的代码,最让我困惑。我阅读了整篇文章,理解了使用阻塞和计算小补丁背后的逻辑,但我不能完全理解这段代码意味着什么:

代码语言:javascript
运行
复制
    // 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;
  }
}

}

有人能详细说明这里面发生了什么吗?这篇文章可以找到这里

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-07-05 02:38:04

文章的第二个注释链接到defs.h#L26,它将float8类型定义为

代码语言:javascript
运行
复制
typedef float float8 __attribute__((ext_vector_type(8)));

(类似于immintrin.h如何定义__m256)。并定义了类似于_mm256_load_ps_mm256_set1_ps的加载/广播功能。使用该标题,您应该能够编译本文中的代码。

Clang的本机矢量文档。GNU本机矢量语法是获得重载*运算符的好方法。我不知道clang的ext_vector_type做什么,GCC/clang/ICC float __attribute__((vector_width(32))) (32字节宽)不会。

这篇文章可以增加一个小部分来解释这一点,但它似乎更多地关注性能细节,而不是真正感兴趣地解释如何使用语法。

本文讨论的大部分内容是如何用SIMD向量手动矢量化匹配以提高缓存效率。从我给它的快速浏览来看,那部分看上去不错。

您可以使用多种方法来完成这些操作: GNU C本地向量或clang非常相似的“扩展”向量,或可移植的Intel内部组件。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62729814

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档