【问题标题】:How to abstract simd code used in template function如何抽象模板函数中使用的simd代码
【发布时间】:2018-05-25 21:31:02
【问题描述】:

假设我有一个函数 add

template<class type>
type* add(type*,type* x, int len)
{
    type *result = new type[len];
    for(int i = 0; i < len; i += simd_reg_size)
    {
      // do addition here
    }
    return result;
}

我想过使用模板特化,以便为我想支持的每种数据类型编写一个专门的添加函数,但是我想到的语法似乎是无效的。

template<>
__m256 SIMD_add<float>(__m256 x, __m256 y){
    return _mm256_add_ps(x, y);
}

我不是 c++ 专家,但据我了解,我必须在参数或参数中使用模板类型。我也想过用类似的东西写一个宏

#define simd_add(x, y, type)
 if type == int
     simd_add_integer(x, y)

但是环顾四周,似乎没有办法在宏中实际执行条件语句。我该怎么办 ?对我来说重要的是语法足够灵活,可以让我抽象出除 x86 之外的 arm 等架构。

【问题讨论】:

  • 您需要专门针对 add 例程吗?你不能只列出每种类型的重载列表吗?然后,您的模板化 add() 函数代码将简单地调用相关的重载。
  • 你的方法的问题是所有的 simd_add 无论类型如何都将它们的输入作为 __mm 寄存器,所以不能重载
  • 啊,这就解释了。 :)
  • 我可能在这里遗漏了一些东西,但是如果你有两个函数用相同的参数类型做两件不同的事情,为什么不给它们不同的名字呢?
  • 因为我希望模板添加通过将自己的模板类型传递给它来简单地使用 SIMD_add。所以我不必多次编写添加函数

标签: c++


【解决方案1】:

事实证明,我可以简单地创建一个模板类,并且所有方法都是静态的,编译器将允许我在不使用函数中的模板类型的情况下进行模板特化。

【讨论】:

    【解决方案2】:

    对于模板函数,特化类型直接定义在您将使用模板类类型的位置,而不像您那样附加到函数名称。

    所以__m256 的专用函数是

    template<>
    __m256 SIMD_add(__m256 x, __m256 y){
        return _mm256_add_ps(x, y);
    }
    

    就像你提到的,如果你想将你的“add”方法添加到模板类中,不管是什么特化,只要将它声明为标准方法即可。

    你可以看看Explicit specializations of function templates,这里有一个关于__m256 registers addition的类似问题。

    【讨论】:

    • 所以将输入参数的类型保持为 __m256 是不可能的吧?
    • 问题是有时我使用 SIMD_add 在 simd 寄存器中累积值。 _mm256_add_ps 返回一个包含 8 个值的寄存器,因此返回浮点数是不可行的。因此,我必须分配一个浮点数组来存储计算结果并返回它。但是,这将完全消除 simd 操作所获得的任何性能改进。
    • 好的,我明白了。我更新了答案以简单地使用“__m256”寄存器类型,抱歉我错过了那部分。感谢您的问题,可能会帮助其他人!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-10-17
    • 2021-08-08
    • 2012-05-09
    • 2021-11-04
    • 1970-01-01
    • 2012-05-05
    • 1970-01-01
    相关资源
    最近更新 更多