【问题标题】:How to compare more than two numbers in parallel?如何并行比较两个以上的数字?
【发布时间】:2012-09-15 12:58:46
【问题描述】:

是否可以使用 SSE4 在一条指令中比较多个数字?

Intel Reference 说以下关于 PCMPGTQ 的内容

PCMPGTQ - 比较打包数据是否大于

对目标中的压缩四字执行 SIMD 比较 操作数(第一个操作数)和源操作数(第二个操作数)。如果 第一个(目标)操作数中的数据元素大于 第二个(源)操作数中的对应元素, 目的地中对应的数据元素设置为全1; 否则设置为0s。

这并不是我真正想要的,因为我希望能够决定向量中哪些整数更大,哪些更小。

例如,如果我需要比较

32 with 45
13 with 78
44 with 12
99 with 66

我打算将 [32, 13, 44, 99] 放入一个向量中,将 [45, 78, 12, 66] 放入另一个向量中,并在一条指令中使用 SSE4 比较它们,并得到 [0, 0, 1, 1] 作为结果(0 - 更少,1 - 更大)

但这似乎不是 PCMPGTQ 所做的。有关如何在此级别使用并行性来加速此比较的任何建议?

【问题讨论】:

  • 您可以将PCMPGTQ 的结果与[1, 1, 1, 1] 相加。还是我错过了什么?
  • 其实我理解错了,PCMPGTQ 确实做了我想做的事。

标签: c algorithm parallel-processing sse sse4


【解决方案1】:

我相信这实际上是 PCMPGT 系列运营商所做的。后缀指定元素的大小 - B 用于 8 位元素,W 用于 16 位元素,D 用于 32 位元素,Q 用于 64 位元素。因此,如果您想一次比较 4 个 32 位数字,请使用 PCMPGTD 和 128 位向量参数。有关这些操作码的伪代码描述,请参阅this page

不过,他们不只写10;他们为每个元素写入全1或全零,因此使用PCMPGTB比较0x12345678876543210x8765432112345678应该得到0x0000FFFFFFFF0000

This Intel white paper 给出了一个使用向量操作执行操作a[i] = (a[i] > b[i]) ? a[i] : b[i](即a[i] = max(a[i], b[i]))的简洁示例。

【讨论】:

  • 谢谢,有点道理。但看起来这个加速并没有给我太多。我可以一次比较 4 个,但如何使用结果?我可能需要做类似if ((int)result[0] == 0) 的事情,因此会引起另一个比较。我肯定错过了什么。
  • @Lazer 取决于周围的代码。如果您只是为了进行一次比较而打包数据,那么您将无法获得任何加速。在打包数据之前,您需要做很多工作才能获得任何有价值的加速。
  • 嗯,当然这取决于你想用它做什么!您可以使用 xorand 来对付这种全为向量的许多巧妙技巧。
  • 感谢 nneonneo 和 @Mystical,我想我明白了。我只需要想办法以最佳方式使用这些结果。
  • @Lazer 他们让它返回全 1 是有原因的。然后你可以用它作为掩码来做一些很酷的事情,比如向量条件移动等等。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-02-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-17
  • 1970-01-01
相关资源
最近更新 更多