22

在实现 SIMD 支持时,我正在阅读英特尔的内在指南。我有一些困惑,我的问题如下。

  1. __m128 _mm_cmpeq_ps (__m128 a, __m128 b)文档说它用于比较打包的单精度浮点数。“打包”是什么意思?我是否需要以某种方式打包我的浮点值才能使用它们?

  2. 对于双精度,有一些内在函数_mm_cmpeq_sd,比如比较“较低”的双精度浮点元素。低位和高位双精度元素是什么意思?我可以使用它们来比较 C++double类型元素的向量吗?或者我需要在比较它们之前以某种方式处理它们吗?

4

2 回答 2

32

在 SSE 中,128 位寄存器可以表示为 4 个 32 位元素或 2 个 64 位元素。

SSE 定义了两种类型的操作;标量和打包。标量运算仅对最不重要的数据元素(位 0~31 或 0~63)进行运算,打包运算并行计算所有元素。

_mm_cmpeq_sd设计用于处理双精度(64 位)浮点元素,并且只会比较两个操作数(标量)的最低有效数据元素(前 64 位)。

_mm_cmpeq_pd被设计用于双精度(64 位)浮点元素,但将并行(打包)比较每两组 64 位。

_mm_cmpeq_ss设计用于处理单精度(32 位)浮点元素,并且只会比较两个操作数(标量)的最低有效数据元素(前 32 位)。

_mm_cmpeq_ps设计用于处理单精度(32 位)浮点元素,并将并行(打包)比较每组 32 位。

如果您使用 32 位浮点数,则可以将浮点数打包成四组以利用 128 位空间。这样,_mm_cmpeq_ps就可以并行进行 4 个比较。

如果您使用的是 64 位双精度,则可以成对打包双精度以利用 128 位空间。这样,_mm_cmpeq_pd就可以并行进行 2 个比较。

如果您一次只想进行一次比较,可以使用_mm_cmpeq_sd比较两个 64 位 double 或_mm_cmpeq_ss比较两个 32 位 float

请注意,_mm_cmpeq_sdand_mm_cmpeq_pd是 SSE2,而_mm_cmpeq_ssand_mm_cmpeq_ps是 SSE。

于 2013-04-25T15:26:20.817 回答
19

在这种情况下,“打包”的意思是“将几个相同类型的东西放在一个块中”——所以“打包的单精度浮点数”是指存储为 128 位值的 4 * 32 位浮点数。

您需要使用各种PACK*指令将每个值“打包”到寄存器中,或者将数据已经“打包”在内存中,例如(多个)4 个浮点值的数组[适当对齐]。

标量表示寄存器低位中的“一个值” n(例如,adouble是 128 位 SSE 寄存器的低 64 位)。

于 2013-04-25T15:26:55.563 回答