提问者:小点点

SIMD 以及打包和标量双精度之间的差异


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

>

  • __m128 _mm_cmpeq_ps(__m128 a,__m128 b)文档称它用于比较压缩单精度浮点。“打包”是什么意思?在使用浮点数之前,我是否需要打包它们?

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


  • 共2个答案

    匿名用户

    在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位)。