field initializer is not constant
-
#include <immintrin.h> struct Test { static constexpr __m128i memberVar = _mm_set1_epi16(12); }; int main() { return 0; } {Bei meiner memberVar beschwert sich g++: "error field initializer is not constant". Mit einfach Datentypen (int,.. ) funktioniert es. Wie kriege ich das mit __m128i hin?
-
Ich würde mal vermuten. das die Funktion _mm_set1_epi16 nicht constexpr ist. Was ist überhaupt ein __m128i?
-
Ein Vektorregister (MMX & Co.) mit insgesamt 128 Bit.
-
hustbaer schrieb:
Ein Vektorregister (MMX & Co.) mit insgesamt 128 Bit.
Wenn das Compiler-Intrinsic ist, ist natürlich schwer zu beantworten. Da müsste man in die Compiler-Doku schauen. Hast du mal versucht, einen constexpr __m128i mit einer Konstanten zu initialisieren? Versuch das mal um den Fehler weiter einzugrenzen.
-
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];} __m128iin 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