- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Is it possible to set the value of a vector of integers with a literal initializer?
For example, it is possible to do:
__m128 x={1.0f,2.0f,3.0f,4.0f};
... and the slots of x are successfully initialized to the values 1.0, 2.0, 3.0, and 4.0 as expected. However, if one attempts
__m128i x={1,2,3,4};
... one finds that the first slot of x is 0x04030201 and the other three slots are all zero. Obviously _mm_set_epi32() provides a fine solution for variables, but what about constants (and convenience)?
So, the question is, is it possible with ICC to do something like:
const __m128i x={1,2,3,4};
...having the obvious intended semantics (as in GCC), without having to do something like:
const __m128i x={1,0,0,0,2,0,0,0,3,0,0,0,4,0,0,0};
...or am I just plain out of luck?
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
_mm_set_epi32() (or _mm_setr_epi32) will get replaced with a constant in data segment and a MOVDQA instruction - I really don't see a reason not to use it.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
_mm_set_epi32() (or _mm_setr_epi32) will get replaced with a constant in data segment and a MOVDQA instruction - I really don't see a reason not to use it.
Hi. Thanks for your suggestion.
I suppose the answer to my question is no, then.
I'd agree with you entirely except that the following construct is forbidden:
const foo=_mm_set_epi32(1,2,3,4);
I'm generating multithreaded code from XML with a lot of read-only constants that can be shared between threads. Heretofore, I've been able to #define them or declare them const and let gcc worry about it. I could, I suppose, declare them with file scope and then add an initialisation function (with a long series of foo=_mm_set_epi32(1,2,3,4);-like lines), called before the threads are created, but that's very ugly, and could conceivably frustrate some compiler optimisations that depend on constants being recognizable as such at compile-time. Unfortunately, it seems that there's no good solution that's portable between icc and gcc.
It turns out that supporting icc requires drastic refactoring for other reasons (icc not being able to use vectors as operands to regular arithmetic operators), which makes support for it (really just an experimental afterthought) a lot more trouble than it's worth for me, so the question is now moot anyway.
Thanks again.
Emmet.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I am not sure how you came to the conclusion that such a construct is forbidden, but for me the following code compiled with icl /c /Od /FAs test.c:
#includevoid test(void) { const __m128i x = _mm_set_epi32(1,2,3,4); }
Compiles successfully and the assembler code looks like this:
... push ebx mov ebx, esp and esp, -16 push ebp push ebp mov ebp, DWORD PTR [ebx+4] mov DWORD PTR [esp+4], ebp mov ebp, esp sub esp, 24 ;;; const __m128i x = _mm_set_epi32(1,2,3,4); movdqa xmm0, XMMWORD PTR _set_pi_cnst$1 movdqa XMMWORD PTR [ebp-24], xmm0 leave mov esp, ebx pop ebx ret ... _RDATA SEGMENT DWORD PUBLIC FLAT 'DATA' _set_pi_cnst$1 DD 4 DD 3 DD 2 DD 1 _RDATA ENDS
I suggest you give it another try.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I honestly never thought of declaring the constants in function scope because they're used all over the place in the code. Both gcc and icc do complain about such a declaration in file scope. Right now, they're in macros that are used extensively in different functions, although that might not be very hard to work around. I wonder if I would get away with using _mm_set_epi32(1,2,3,4) instead of ((v4si){1,2,3,4}) as I do at the moment (for gcc). Off the top of my head, I can't see any reason why not, and it probably wouldn't be any worse than what I'm already doing.
Thanks again for your help and time: you've been very helpful.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You are welcome.
It may be a problem if you have a need for global constants but there is also a way around that, namely:
// global scope (file level) #define ALIGN __declspec(align(16)) ALIGN const int cvx[4] = { 1, 2, 3, 4 };
And then later in the code you write:
_mm_load_si128((__m128i*)&cvx)
In the place of yourx variable. It will generate the same MOVDQA instruction.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Usually it is better for the compiler to decide which instructions to use and rely on automatic vectorization. If the code using the constant is automatically vectorized, no intrinsics are needed, because the constant is stored as a 128 bit value, like this
__declspec(align(16)) static const int cvx[4] = { 1, 2, 3, 4 };
movdqa xmm0, XMMWORD PTR cvx$301$0$0
In another case when code is not suitable for vector instructions, other isntructions may be preferred to load the data - let the compiler decide!
Best Regards,
Lars Petter Endresen
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Usually it is better for the compiler to decide which instructions to use and rely on automatic vectorization. If the code using the constant is automatically vectorized, no intrinsics are needed, because the constant is stored as a 128 bit value, like this
__declspec(align(16)) static const int cvx[4] = { 1, 2, 3, 4 };
movdqa xmm0, XMMWORD PTR cvx$301$0$0
In another case when code is not suitable for vector instructions, other isntructions may be preferred to load the data - let the compiler decide!
Best Regards,
Lars Petter Endresen
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page