如何在不使用任何SSE指令的情况下设置

编程入门 行业动态 更新时间:2024-10-25 04:16:56
本文介绍了如何在不使用任何SSE指令的情况下设置__m128i?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我有很多函数使用相同的常量__m128i值. 例如:

I have many function which use the same constant __m128i values. For example:

const __m128i K8 = _mm_setr_epi8(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); const __m128i K16 = _mm_setr_epi16(1, 2, 3, 4, 5, 6, 7, 8); const __m128i K32 = _mm_setr_epi32(1, 2, 3, 4);

所以我想将所有这些常量存储在一个地方. 但是有一个问题:我在运行时检查现有的CPU扩展. 如果CPU不支持SSE(或AVX),则在常量初始化期间将导致程序崩溃.

So I want to store all these constants in an one place. But there is a problem: I perform checking of existed CPU extension in run time. If the CPU doesn't support for example SSE (or AVX) than will be a program crash during constants initialization.

那么不使用SSE就可以初始化这些常量吗?

So is it possible to initialize these constants without using of SSE?

推荐答案

可以在不使用SSE指令的情况下初始化__m128i向量,但这取决于编译器定义__m128i的方式.

Initialization of __m128i vector without using SSE instructions is possible but it depends on how to compiler defines __m128i.

对于Microsoft Visual Studio,您可以定义下一个宏(它将__m128i定义为char [16]):

For Microsoft Visual Studio you can define next macros (it defines __m128i as char[16]):

template <class T> inline char GetChar(T value, size_t index) { return ((char*)&value)[index]; } #define AS_CHAR(a) char(a) #define AS_2CHARS(a) \ GetChar(int16_t(a), 0), GetChar(int16_t(a), 1) #define AS_4CHARS(a) \ GetChar(int32_t(a), 0), GetChar(int32_t(a), 1), \ GetChar(int32_t(a), 2), GetChar(int32_t(a), 3) #define _MM_SETR_EPI8(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, aa, ab, ac, ad, ae, af) \ {AS_CHAR(a0), AS_CHAR(a1), AS_CHAR(a2), AS_CHAR(a3), \ AS_CHAR(a4), AS_CHAR(a5), AS_CHAR(a6), AS_CHAR(a7), \ AS_CHAR(a8), AS_CHAR(a9), AS_CHAR(aa), AS_CHAR(ab), \ AS_CHAR(ac), AS_CHAR(ad), AS_CHAR(ae), AS_CHAR(af)} #define _MM_SETR_EPI16(a0, a1, a2, a3, a4, a5, a6, a7) \ {AS_2CHARS(a0), AS_2CHARS(a1), AS_2CHARS(a2), AS_2CHARS(a3), \ AS_2CHARS(a4), AS_2CHARS(a5), AS_2CHARS(a6), AS_2CHARS(a7)} #define _MM_SETR_EPI32(a0, a1, a2, a3) \ {AS_4CHARS(a0), AS_4CHARS(a1), AS_4CHARS(a2), AS_4CHARS(a3)}

对于GCC,它将是(将__m128i定义为long long [2]):

For GCC it will be (it defines __m128i as long long[2]):

#define CHAR_AS_LONGLONG(a) (((long long)a) & 0xFF) #define SHORT_AS_LONGLONG(a) (((long long)a) & 0xFFFF) #define INT_AS_LONGLONG(a) (((long long)a) & 0xFFFFFFFF) #define LL_SETR_EPI8(a, b, c, d, e, f, g, h) \ CHAR_AS_LONGLONG(a) | (CHAR_AS_LONGLONG(b) << 8) | \ (CHAR_AS_LONGLONG(c) << 16) | (CHAR_AS_LONGLONG(d) << 24) | \ (CHAR_AS_LONGLONG(e) << 32) | (CHAR_AS_LONGLONG(f) << 40) | \ (CHAR_AS_LONGLONG(g) << 48) | (CHAR_AS_LONGLONG(h) << 56) #define LL_SETR_EPI16(a, b, c, d) \ SHORT_AS_LONGLONG(a) | (SHORT_AS_LONGLONG(b) << 16) | \ (SHORT_AS_LONGLONG(c) << 32) | (SHORT_AS_LONGLONG(d) << 48) #define LL_SETR_EPI32(a, b) \ INT_AS_LONGLONG(a) | (INT_AS_LONGLONG(b) << 32) #define _MM_SETR_EPI8(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, aa, ab, ac, ad, ae, af) \ {LL_SETR_EPI8(a0, a1, a2, a3, a4, a5, a6, a7), LL_SETR_EPI8(a8, a9, aa, ab, ac, ad, ae, af)} #define _MM_SETR_EPI16(a0, a1, a2, a3, a4, a5, a6, a7) \ {LL_SETR_EPI16(a0, a1, a2, a3), LL_SETR_EPI16(a4, a5, a6, a7)} #define _MM_SETR_EPI32(a0, a1, a2, a3) \ {LL_SETR_EPI32(a0, a1), LL_SETR_EPI32(a2, a3)}

因此在您的代码中,__ m128i常量的初始化将类似于:

So in your code initialization of __m128i constant will be look like:

const __m128i K8 = _MM_SETR_EPI8(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); const __m128i K16 = _MM_SETR_EPI16(1, 2, 3, 4, 5, 6, 7, 8); const __m128i K32 = _MM_SETR_EPI32(1, 2, 3, 4);

更多推荐

如何在不使用任何SSE指令的情况下设置

本文发布于:2023-11-11 06:53:11,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1577686.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:指令   情况下   如何在   SSE

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!