是否有GNU __builtin_ia32函数(对于Visual Studio编译器)的等价物?

时间:2016-11-28 09:29:26

标签: c++ gcc simd intrinsics

我希望移植一个现有的C ++代码,该代码经过优化,可以使用GNU编译器运行向量操作,以便使用Visual Studio编译器进行编译。

本程序使用专门的GNU单指令多数据(SIMD)内在指令(参见例如GCC - Vector Extensions)。

由于这些内在函数似乎只是GNU编译器,如果有人知道是否有办法将数据类型和函数移植到其他编译器(在我的情况下是msvc12),我会非常高兴。

基本上有两个但非常密切相关的问题。 1.是否可以以类似的方式为其他编译器构建以下数据类型? (这些是16个字节的变量,包含例如四个int或十六个char。)

   // Integer types
   typedef char     v16qi __attribute__ ((vector_size (16), aligned (16)));
   typedef short     v8hi __attribute__ ((vector_size (16), aligned (16)));
   typedef int       v4si __attribute__ ((vector_size (16), aligned (16)));
   typedef long long v2di __attribute__ ((vector_size (16), aligned (16)));

   // Floating point types
   typedef float     v4sf __attribute__ ((vector_size (16), aligned (16)));
   typedef double    v2sf __attribute__ ((vector_size (16), aligned (16)));
  1. 在哪里可以找到以下函数的描述和与编译器无关的等价物?

    __ builtin_ia32_loaddqu, __builtin_ia32_paddsb128, __builtin_ia32_paddusb128, __builtin_ia32_pavgb128, __builtin_ia32_pcmpgtb128, __builtin_ia32_pmovmskb128, __builtin_ia32_psadbw128, __builtin_ia32_psrlwi128, __builtin_ia32_psubsb128, __builtin_ia32_psubusb128, __builtin_ia32_punpckhbw128, __builtin_ia32_pxor128, __builtin_ia32_storedqu

  2. 我已经深入搜索了这个主题,但找不到我的问题的直接答案。我知道存在适用于msvc12的数据类型,如__m128__m128i__m128d(请参阅例如Microsoft Developer Network - Streaming SIMD Extensions (SSE)),但我无法将两者结合在一起。

    是否可以"简单地"替换typedef__builtin_ia32函数?

    如果我对任何细节更具体,请发表评论。我试着保持这个问题简短。 我会非常感谢任何帮助!非常感谢您的回答。

1 个答案:

答案 0 :(得分:1)

我可以避免代码中的一些功能。对于其余部分,以下为我完成了这项工作(我最终可以确定emmintrin.h中的相应函数以及MinGW gcc编译器的include目录中的类似文件)与Agner Fog上的vectorclass库相结合@PeterCordes评论过(感谢您的帮助)。

#ifdef _MSC_VER
#define __builtin_ia32_psadbw128(_A, _B)  _mm_sad_epu8((__m128i) _A, (__m128i) _B)
#define __builtin_ia32_paddsb128(_A, _B)  _mm_adds_epi8((__m128i) _A, (__m128i) _B)
#define __builtin_ia32_pmovmskb128(_A)    _mm_movemask_epi8((__m128i) _A)
#define __builtin_ia32_pcmpgtb128(_A, _B) _mm_cmpgt_epi8((__m128i) _A, (__m128i) _B)
#define __builtin_ia32_psubsb128(_A, _B)  _mm_subs_epi8((__m128i) _A, (__m128i) _B)
#define __builtin_ia32_psubusb128(_A, _B) _mm_subs_epu8((__m128i) _A, (__m128i) _B)
#define __builtin_ia32_pavgb128(_A, _B)   _mm_avg_epu8((__m128i) _A, (__m128i) _B)
#define __builtin_ia32_paddusb128(_A, _B) _mm_adds_epu8((__m128i) _A, (__m128i) _B)
#define __builtin_ia32_psrlwi128(_A, _B)  _mm_srli_epi16((__m128i) _A, _B)
#define __builtin_popcountll(_X)          _mm_popcnt_u64((unsigned long long) _X)
#endif

可能内联函数比上面的define更优雅。