自定义数据类型的 SIMD 指令
SIMD instructions on custom data types
我发现使用 SIMD 指令的矢量化数据类型进行编程(this tutorial)。据我了解,向量的大小固定为 16 个字节。这个示意图详细说明了它,似乎回答了我的问题:
提供了一组说明,包括基本操作(但也包括一些更具体的操作)。
不过,出于好奇,我想知道是否有矢量化 "custom data" 的方法,我指的主要是结构。我想如果结构的大小在 16 字节范围内,这是可能的,因为最后,类型只是字节大小,但是指令集似乎不允许直接对结构进行操作,例如获取字段。
所以我的问题如下:在向量化和 SIMD 操作时,我们是否仅限于简单的标准 C 类型?如果没有,我们如何进行?如果是,是否有并行化方法(多线程除外)可以同时对结构向量/数组进行操作?
_mm_loadu_si128
/ _mm_storeu_si128
是严格别名安全的,所以你可以在任何地方使用它们。 ARM NEON 的等效项类似。
如果您知道结构布局(对于给定的 ABI 是固定的),您肯定可以 load/store 来自结构或结构数组的大块数据。例如 does packed conversion then shuffle and blend. Another example:
你可以用 asm 做的大部分事情都可以在 C 中使用内在函数来实现。
如果你想对每个结构成员做不同的事情,那么你通常会遇到问题。例如struct xy { float x,y; };
几何向量不适合 SIMD。添加很好(它是纯垂直的),但点积或旋转需要在 SIMD 向量中水平组合单个几何向量的 x 和 y 分量。洗牌需要额外的指令。
这是结构数组问题,通常最好通过将数据存储为数组数组的一个结构来解决。所以你有 float x[]
和 float y[]
,这样你就可以在 x[i + 0..3]
、y[i + 0..3]
和 x[j + 0..3]
之间一次完成四个点积的整个 SIMD 向量, y[j + 0..3]
.
请参阅 https://whosebug.com/tags/sse/info for some links, specifically Slides: SIMD at Insomniac Games (GDC 2015),其中还随每张幻灯片转录了演讲文本。它通过一些图表对这些概念进行了更循序渐进的介绍。
我发现使用 SIMD 指令的矢量化数据类型进行编程(this tutorial)。据我了解,向量的大小固定为 16 个字节。这个示意图详细说明了它,似乎回答了我的问题:
提供了一组说明,包括基本操作(但也包括一些更具体的操作)。
不过,出于好奇,我想知道是否有矢量化 "custom data" 的方法,我指的主要是结构。我想如果结构的大小在 16 字节范围内,这是可能的,因为最后,类型只是字节大小,但是指令集似乎不允许直接对结构进行操作,例如获取字段。
所以我的问题如下:在向量化和 SIMD 操作时,我们是否仅限于简单的标准 C 类型?如果没有,我们如何进行?如果是,是否有并行化方法(多线程除外)可以同时对结构向量/数组进行操作?
_mm_loadu_si128
/ _mm_storeu_si128
是严格别名安全的,所以你可以在任何地方使用它们。 ARM NEON 的等效项类似。
如果您知道结构布局(对于给定的 ABI 是固定的),您肯定可以 load/store 来自结构或结构数组的大块数据。例如
你可以用 asm 做的大部分事情都可以在 C 中使用内在函数来实现。
如果你想对每个结构成员做不同的事情,那么你通常会遇到问题。例如struct xy { float x,y; };
几何向量不适合 SIMD。添加很好(它是纯垂直的),但点积或旋转需要在 SIMD 向量中水平组合单个几何向量的 x 和 y 分量。洗牌需要额外的指令。
这是结构数组问题,通常最好通过将数据存储为数组数组的一个结构来解决。所以你有 float x[]
和 float y[]
,这样你就可以在 x[i + 0..3]
、y[i + 0..3]
和 x[j + 0..3]
之间一次完成四个点积的整个 SIMD 向量, y[j + 0..3]
.
请参阅 https://whosebug.com/tags/sse/info for some links, specifically Slides: SIMD at Insomniac Games (GDC 2015),其中还随每张幻灯片转录了演讲文本。它通过一些图表对这些概念进行了更循序渐进的介绍。