F
Die SIMD-Typen wie __m128i sind soweit ich weiss Compiler-spezifische typedefs, wie z.B. typedef long long __m128i __attribute__ ((__vector_size__ (16), __may_alias__)) in GCC oder
typedef union __declspec(intrin_type) __declspec(align(16)) {char c[16];} __m128i in Visual C.
Wenn du diese statisch als constexpr initialisieren möchtest, wirst du diese Variablen wohl mit einem Ausdruck initialisieren müssen, der für den entsprechenden Compiler passt, also z.B. { 0, 12, 0, 12, 0, 12, 0, 12, 0, 12, 0, 12, 0, 12, 0, 12 } in Visual C.
Das ist allerdings nicht sehr portabel und nicht gerade bequem wenn man wie du 16bit-Integer in die SIMD-Variable schrieben möchte.
Ich würde daher eher so etwas hier vorschlagen:
struct Test
{
alignas(16) static constexpr std::int16_t memberVar[8] = { 12, 12, 12, 12, 12, 12, 12, 12 };
};
alignas(16) constexpr std::int16_t Test::memberVar[8];
Damit machst du dann alles zur Compile-Zeit weswegen du überhaupt in erster Linie die constexpr benötigst. Sobald du dann anfängst mit den Werten tatsächlich in einem SIMD-Register zu rechnen, lädst diese dann aus dem Speicher:
__m128i r1 = _mm_load_si128(reinterpret_cast<const __m128i*>(Test::memberVar));
ich weiss nicht ob das das eleganteste Weg ist, aber diesen würde ich persönlich einschlagen, wenn die Werte, mit denen die SIMD-Variablen initialisiert werden, undbedingt ein constexpr-Ausruck sein müssen.
Gruss,
Finnegan