如何根据宏中的类型做出决定?

时间:2014-08-27 10:50:17

标签: c++ if-statement c++11 macros code-generation

在我的公司,我正致力于为一些热门代码提供更快的SSE路径。我使用内在的方法来保持C ++并且真正显示出令人印象深刻的结果。

所有代码只需要处理floatdouble,因此我创建了一个模板化的SSE操作类,我专门为它们编写。我真正不喜欢的是这两个类看起来几乎相同,除了数字类型(float / double),使用的SSE类型(__m128 / {{1 }}和intrisics后缀(__m128d / _ps)如下:

_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()主题严重污染了结果,因此搜索解决方案出乎意料。谁能告诉我如何针对这个问题做出宏观层面的决定呢?

PS:我听说过Boost Preprocessor,但我不允许使用它。

更新虽然我要求提供宏解决方案,但我也会接受一个不错的模板解决方案。为此,要知道我至少要封装7个内在函数 - 以防万一会破坏模板代码。

1 个答案:

答案 0 :(得分:0)

您可以通过特征摆脱第二个参数:

template <class Scalar>
struct Vector;

template <>
struct Vector<float>
{
  typedef __m128 type;
};

template <>
struct Vector<double>
{
  typedef __m128d type;
};

至于第三个,你可以做一个真正的丑陋的特殊预处理器 hack 技巧:

#define SUFFIX_float ps
#define SUFFIX_double pd

并在##上使用SUFFIX_和最外层的宏参数来获得正确的版本。当然,它需要一些间接级别才能使宏在正确的时间扩展。使用Boost.Preprocessor,特别是BOOST_PP_CAT和可能BOOST_PP_EXPAND,可能会使这一点变得更容易。