C &引用;扩展;SSE寄存器中的数据类型大小

C &引用;扩展;SSE寄存器中的数据类型大小,c,sse,simd,C,Sse,Simd,我正在使用VS2005(在工作中),需要一个SSE内在函数,它可以执行以下操作: 我有一个预先存在的\uum128in,其中填充了16位整数a\u1,a\u2,…,a\u8 由于我现在想做的一些计算需要32位而不是16位,所以我想从n中提取两组四组16位整数,并将它们分别放入两个独立的\um128is中,其中包含a\u1,…,a\u4和a\u5,…,a\u8 我可以使用各种\u mm_集内部函数手动完成这项工作,但这些函数会在汇编中产生八个mov,我希望有一种更快的方法来完成这项工作。假设我正确

我正在使用VS2005(在工作中),需要一个SSE内在函数,它可以执行以下操作:

我有一个预先存在的
\uum128i
n,其中填充了16位整数
a\u1,a\u2,…,a\u8

由于我现在想做的一些计算需要32位而不是16位,所以我想从n中提取两组四组16位整数,并将它们分别放入两个独立的
\um128i
s中,其中包含
a\u1,…,a\u4
a\u5,…,a\u8


我可以使用各种
\u mm_集
内部函数手动完成这项工作,但这些函数会在汇编中产生八个
mov
,我希望有一种更快的方法来完成这项工作。

假设我正确理解了您想要实现的目标(将一个向量中的8 x 16位解压为两个4 x 32位内部函数的向量),我通常在SSE2和更高版本中这样做:

__mm128i v = _mm_set_epi16(7, 6, 5, 4, 3, 2, 1, 0);  // v = { 7, 6, 5, 4, 3, 2, 1, 0 }
__mm128i v_lo = _mm_srai_epi32(_mm_unpacklo_epi16(v, v), 16); // v_lo = { 3, 2, 1, 0 }
__mm128i v_hi = _mm_srai_epi32(_mm_unpackhi_epi16(v, v), 16); // v_hi = { 7, 6, 5, 4 }

看看这些。你可以通过使用其中的两个和一个解包/洗牌来得到你想要的。我认为它们在VS2005中不可用。Eek。。。VS2005。告诉你的老板烧掉它。。。有火。:)否则。。。你被困在一个混乱不堪的洗牌、轮班和面具的长途跋涉中。很好。。。这并不像我想象的那么糟糕。当然,我从来没有努力过,因为我通常可以访问SSE4.1。但这会比v_lo=_mm_set_epi32(a_1,…,a_4)v_hi=_mm_set_epi32(a_5,a_6,a_7,a_8)更快吗?我可以通过内部的uu m128i访问单个值,它似乎是一个联合体,我可以在其中访问各种包含的数据类型,如数组。@TravisG Everything将比使用
\u mm\u set
和提取单个组件更快。您的代码要做的是将这些值从SSE寄存器中取出,放入一些对齐的内存存储器中,对每个值执行一些非SSE操作,然后将其加载到另一个寄存器中。这将比在苏格兰和南方能源公司登记册上用一堆SEE ops执行这一切要慢很多联盟。一般来说,从SSE寄存器访问单个组件是任何SSE代码的性能杀手,无论您的库是否通过提供union…@TravisG…使其易于编程,这并不是说您只会失去SIMD并行性。整个单组件访问必须由一系列内存操作支持,因为SSE不是为此而构建的。@TravisG:除了Christian的有效注释外,我只想说上面的代码,尽管看起来很糟糕,但只翻译成4条指令。如果您开始使用标量代码处理单个向量元素,那么您将看到超过4条指令(加上前面提到的所有其他问题)。