【问题标题】:indexing into an array with SSE使用 SSE 对数组进行索引
【发布时间】:2011-05-27 21:32:11
【问题描述】:

假设我有一个数组:

uint8_t arr[256];

和一个元素

__m128i x

包含 16 个字节,

x_1, x_2, ... x_16

我想有效地填充一个新的__m128i 元素

__m128i y

来自arr 的值取决于x 中的值,例如:

y_1  = arr[x_1]
y_2  = arr[x_2]
   .
   .
   .
y_16 = arr[x_16]

实现这一点的命令本质上是从一组不连续的内存位置加载一个寄存器。我对看过这样一个命令的文档有一种痛苦的模糊记忆,但现在找不到了。它存在吗?提前感谢您的帮助。

【问题讨论】:

  • 修复了代码格式;以后,请记住,如果要将文本块格式化为代码,则必须缩进 4 个空格并在其前面留一个空行(或者只需选择它并按 0101 按钮)。
  • @Matteo:不再是101010。改为{ }...
  • @thkala:呃,我没注意到,一般来说我只是从编辑器中执行 CTRL-K 或复制粘贴,我可以在其中添加 4 个空格按 TAB(我可以从语法中受益突出显示)。

标签: c sse simd


【解决方案1】:

SIMD 架构中的这种功能称为加载/存储分散/收集。不幸的是,SSE 没有。英特尔未来的 SIMD 架构可能会有这种情况——命运多舛的 Larrabee 处理器就是一个很好的例子。目前,您只需要以不需要这种功能的方式设计数据结构。

请注意,您可以通过使用例如_mm_set_epi8:

y = _mm_set_epi8(arr[x_16], arr[x_15], arr[x_14], ..., arr[x_1]);

当然,这只会生成一堆标量代码来加载您的 y 向量。如果您在任何性能关键循环之外执行此类操作,这很好,例如作为循环之前初始化的一部分,但在循环内部它可能会成为性能杀手。

【讨论】:

  • 感谢您的回答。 “聚集/分散”显然是我正在寻找的术语。经过简单检查后,GPU 上似乎可以使用此类功能。有什么建议吗?
  • 即使在 GPU 上,这也可能是低效的,因为从不同的内存地址加载/存储将不可避免地意味着更多的总线周期。
  • _mm_set_epi8 允许您在__m128i 中执行负载(一些手放弃)。从__m128i到数组元素怎么做类似的存储?
  • @jww:没有方便或有效的方法来使用 SSE 进行分散存储 - 我可能只会使用联合和循环来执行存储。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-01-07
  • 2020-03-29
  • 2019-03-31
  • 2020-02-27
  • 2013-10-28
相关资源
最近更新 更多