我希望移植一个现有的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)));
在哪里可以找到以下函数的描述和与编译器无关的等价物?
__ 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
我已经深入搜索了这个主题,但找不到我的问题的直接答案。我知道存在适用于msvc12的数据类型,如__m128
,__m128i
和__m128d
(请参阅例如Microsoft Developer Network - Streaming SIMD Extensions (SSE)),但我无法将两者结合在一起。
是否可以"简单地"替换typedef
和__builtin_ia32
函数?
如果我对任何细节更具体,请发表评论。我试着保持这个问题简短。 我会非常感谢任何帮助!非常感谢您的回答。
答案 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
更优雅。