2017-06-01 43 views
1

我想写一个网点位select功能打包SSE2双打:优化网点条件选择包装双打

#include <iostream> 
#include <emmintrin.h> 

inline __m128d select(bool expression, const __m128d& x, const __m128d& y) 
{ 
    const int conditional_mask = expression ? -1 : 0; 

    const auto mask = _mm_castsi128_pd(_mm_set_epi64x(conditional_mask, conditional_mask)); 

    return _mm_or_pd(_mm_and_pd(mask, x), _mm_andnot_pd(mask, y)); 
} 

int main() 
{ 
    auto r1 = _mm_setr_pd(1, 2); 
    auto r2 = _mm_setr_pd(5, 6); 

    auto result = select(true, r1, r2); 

    auto packed = reinterpret_cast<double*>(&result); 

    std::cout << "result = " << packed[0] << ", " << packed[1] << std::endl; 
    std::getchar(); 

    return EXIT_SUCCESS; 
} 

是否有SSE2和SSE4一个简单的方法,这将是更优化64?

回答

4

您已经指定了SSE4是允许的,SSE4.1有blendvpd,所以你可以用内置的混合交融:(未测试,但编译)

inline __m128d select(bool expression, const __m128d& x, const __m128d& y) 
{ 
    const int c_mask = expression ? -1 : 0; 
    const auto mask = _mm_castsi128_pd(_mm_set_epi64x(c_mask, c_mask)); 
    return _mm_blendv_pd(y, x, mask); 
} 

我也不会采取SSE矢量作为引用的参数,复制它们是微不足道的,所以不是要避免的,并且通过引用来引用它们会鼓励编译器通过内存(对于非内联调用)反弹它们。

+0

我可以证实这个作品,好电话:-) – keith