SIMD和打包和标量双精度之间的区别

use*_*001 17 c++ x86 sse simd intrinsics

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

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

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

zak*_*ter 23

在SSE中,128位寄存器可以表示为32位的4个元素.

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

_mm_cmpeq_sd只比较两个操作数的最低有效数据元素(前32位),而_mm_cmpeq_ps并行比较每组32位.

如果您使用的是64位双精度数,则可以逐对打包以使用128位空间.这样,_mm_cmpeq_ps就可以并行地进行4个双倍的比较.

如果您想一次只进行一次比较,可以使用_mm_cmpeq_pd两个64位比较来比较.

注意_mm_cmpeq_pdSSE2 _mm_cmpeq_ps是SSE.

  • @zkoza 是的,双精度和浮点运算之间存在混淆,感谢您指出这一点。我在上次编辑中修复了它,并添加了所有四个标量/压缩和单/双操作以避免任何混淆。 (2认同)

Mat*_*son 13

在这种情况下,"打包"表示"几个相同类型放入一个块" - 因此"打包单精度浮点"表示存储为128位值的4*32位浮点数.

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

标量表示n寄存器低位的"一个值" (例如,a double将是128位SSE寄存器的低64位).