在实施SIMD支持时,我正在阅读英特尔的内部指南。我有一些困惑,我的问题如下。
>
__m128 _mm_cmpeq_ps(__m128 a,__m128 b)
文档称它用于比较压缩单精度浮点。“打包”是什么意思?在使用浮点数之前,我是否需要打包它们?
对于双精度,有像_mm_cmpeq_sd
这样的内在函数,这意味着比较“较低”的双精度浮点元素。较低和较高的双精度元素是什么意思?我可以使用它们来比较C双
类型元素的向量吗?或者我需要在比较它们之前以某种方式处理它们吗?
在SSE中,128位寄存器可以表示为32位的4个元素或64位的2个元素。
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位的double,你可以把double成对打包,以利用128位的空间。这样,< code>_mm_cmpeq_pd将能够并行进行两次比较。
如果您想一次只进行一次比较,可以使用< code>_mm_cmpeq_sd比较两个64位double,或者使用< code>_mm_cmpeq_ss比较两个32位float。
请注意,< code>_mm_cmpeq_sd和< code>_mm_cmpeq_pd是SSE2,而< code>_mm_cmpeq_ss和< code>_mm_cmpeq_ps是SSE。
在此上下文中,“packed”表示“将几个相同类型的组合成一个块” - 因此“packed单精度浮点”表示存储为128位值的4 * 32位浮点数。
您需要使用各种 PACK*
指令将每个值“打包”到寄存器中,或者将数据“打包”到内存中,例如 4 个浮点值的(倍数)数组 [适当对齐]。
标量表示寄存器较低n
位中的“一个值”(例如,双精度
是128位SSE寄存器的低64位)。