如何在没有性能命中的情况下抽象SIMD代码来处理不同的数据类型

How to Abstract SIMD code to handle different datatypes without a performance hit

本文关键字:代码 SIMD 处理 数据类型 抽象 情况下 性能      更新时间:2023-10-16

我一直在编写用于执行矩阵操作的代码。最初,它仅适用于X86,现在将其移植到不同的架构中。另外,我希望它支持Float以外的不同数据类型。

考虑以下添加到float数组的代码

void add(float *a, float *b, float *dst, int len)
{
        int k = 0;
        for(; k + 8 <  len; k += 8,a +=  8, b += 8, dst+= 8){
            __m256 x = _mm256_load_ps(a);
            __m256 y = _mm256_load_ps(b);
            __m256 z = _mm256_add_ps(x, y);
            _mm256_store_ps(dst, z);
        }
}

这是我考虑的改进代码以支持多种平台和数据类型的代码。

  1. 对于不同的数据类型,我将将函数更改为模板函数

  2. 对于SIMD指令,我想到拥有将所有架构特定特定固有函数重命名为simd simd_add等通用simd指令的宏。问题是不同的数据类型需要不同的固有函数,并且内在的返回类型也取决于数据类型。

  3. 同样,如果我要编写减去功能,我最终将复制大多数代码,只是为了替换simd_add宏的simd_sub宏。它们的整洁方式使我不必重复所有元素操作的相同代码,例如乘法,除法和减法?

一个人将如何应对点2&amp;3不抽象影响代码的性能?

我最终为每个数据类型提供了专业化的SIMD指令的模板类。不幸的是,编译器不会自动内联,因此您必须使用编译器特定属性将其迫使它限制为inline