【发布时间】:2014-10-20 22:11:16
【问题描述】:
在我的公司,我正在努力为一些热门代码提供更快的 SSE 路径。我正在使用与 C++ 保持一致的内在方法,并且确实显示出令人印象深刻的结果。
所有代码只需要在float 和double 上工作,所以我创建了一个模板化的 SSE 操作类,我专门针对这两个类。我真正不喜欢的是这两个类看起来几乎相同,除了数字类型(float/double)、使用的 SSE 类型(__m128/__m128d)和 intrisics 后缀(@987654328 @/_pd) 像这样:
template<>
struct SseOperations<float> : public Sse<float>
{
typedef __m128 vector;
vector load(float const * const from) const
{
return _mm_loadu_ps(from);
}
vector add(vector const & a, vector const & b) const
{
return _mm_add_ps(a, b);
}
// etc.
};
和
template<>
struct SseOperations<double> : public Sse<double>
{
typedef __m128d vector;
vector load(double const * const from) const
{
return _mm_loadu_pd(from);
}
vector add(vector const & a, vector const & b) const
{
return _mm_add_pd(a, b);
}
// etc.
};
由于内部函数后缀不同,我不知道如何使用模板魔法来统一它。
然后我想到了宏的## 功能,它可以用于此目的。所以我设法将完整的专业类放入一个宏中,我可以用它来生成两个类:
SSE_OPERATIONS(float, __m128, _ps);
SSE_OPERATIONS(double, __m128d, _pd);
我知道宏是邪恶的,但至少在这种情况下我没有看到任何典型的危险并且它完成了工作。
现在困扰我的是第二个和第三个宏参数是多余的;它们可以从第一个推断出来,只是我完全不知道如何。 #if 及其朋友不应该工作,因为 sizeof() 在预处理期间不起作用。
搜索解决方案出乎意料地困难,因为#if 主题严重污染了结果。谁能告诉我如何针对这个问题做出宏观决策?
PS:我听说过Boost Preprocessor,但我不能使用它。
更新:虽然我要求的是宏解决方案,但我也会接受一个不错的模板解决方案。为此,要知道我封装了至少 7 个内部函数——以防模板代码膨胀。
【问题讨论】:
-
如果你可以用宏来做到这一点,你也可以不用宏来做到这一点。
-
我看不出宏参数是如何冗余的。这 3 个名称在令牌级别上完全不相关。您的宏必须必须说明这 3 个令牌之间的逻辑关系。你不能从`float
. Of course, this ultimately is caused by the extremely limited integration of SSE primitives and C++. If the responsible compiler developer had understood both, he'd have realized thatoperator+`中推断出_ps是_mm_add_pd的一个完全理智的名字。运算符重载已有数十年历史;今天无需继续对程序施加汇编程序限制。 -
好吧,它们对 PP 来说不是多余的,但对我来说。如果我有一个宏 if,我可以只在给定
float或double的宏的开头计算/设置它们。
标签: c++ if-statement c++11 macros code-generation