【发布时间】:2016-11-28 09:29:26
【问题描述】:
我想移植一个现有的 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)),但我无法将两者结合在一起。
是否可以“简单地”替换 typedefs 和 __builtin_ia32 函数?
如果我应该对任何细节更具体,请发表评论。我试图让问题简短。 如果有任何帮助,我将不胜感激!非常感谢您的回答。
【问题讨论】:
-
AFAIK,如果您需要在 MSVC 上进行手动矢量化,最好的办法是重写代码以使用 Intel 的内在函数。使用
__m128i数据类型和像_mm_add_epi32这样的内在函数。见software.intel.com/sites/landingpage/IntrinsicsGuide。 (以及x86 tag wiki 中的其他链接)。 -
AFAIK,MSVC 没有像
typedef short v8hi __attribute__ ((vector_size (16), aligned (16)));这样的东西,可以让您使用+运算符来获取 PADDW。但是Agner Fog's (GPLed) vectorclass library 确实提供了 v4si 和 C++ 运算符重载等类。它至少可以移植到 MSVC、gcc、clang 和 icc。 -
非常感谢您的回复,@PeterCordes!事实上,使用
v8hi c = a + b之类的东西非常方便。我会看看你提到的vectorclass库,它似乎真的很好。这和您答案中的链接将帮助我继续。坦克! -
请记住,Agner 的矢量类库是 GPL 的,因此您不能在闭源项目中使用它。还有其他类似的 SIMD 封装库,但我没有看过。
标签: c++ gcc simd intrinsics