我发现使用SIMD指令的矢量化数据类型进行编程(this tutorial)。据我了解,向量的固定大小为16个字节。这个原理图很好地详述了它,似乎可以回答我的问题:
提供了包括基本操作的指令集(但还有一些更具体的指令)。
尽管如此,出于好奇,我想知道是否存在矢量化“自定义数据”的方法,在此我主要指的是结构。我想如果结构的大小在16个字节的范围内,那是有可能的,因为最后类型只是字节大小,但是指令集似乎不允许直接在结构上进行操作,例如得到一个领域。
所以我的问题是:矢量化和SIMD操作时,我们是否限于简单的标准C类型?如果没有,我们该如何进行?如果是,是否有并行方法(多线程之外)可同时对结构向量/数组进行操作?
_mm_loadu_si128
/ _mm_storeu_si128
是严格混叠安全的,因此您可以在任何东西上使用它们。 ARM NEON的等效项相似。
如果知道结构布局(对于给定的ABI是固定的),则可以肯定地可以从结构或结构数组中大块加载/存储数据。例如Fast interleave 2 double arrays into an array of structs with 2 float and 1 int (loop invariant) member, with SIMD double->float conversion?执行压缩转换,然后随机播放和混合。另一个例子:Sorting 64-bit structs using AVX?
您可以使用内置函数在C语言中使用asm进行大多数操作。
但是,如果您想对每个struct成员执行不同的操作,那么通常会遇到问题。例如struct xy { float x,y; };
几何矢量不太适合SIMD。加法很好(它是纯垂直的),但是点积或旋转需要在SIMD矢量内水平组合单个几何矢量的x和y分量。改组需要额外的说明。
这是结构数组问题,通常最好通过将数据存储为一个结构of of arrays >>来最好地解决。因此,您将拥有 请参见https://stackoverflow.com/tags/sse/info以获取某些链接,特别是Slides: SIMD at Insomniac Games (GDC 2015),该链接还随每张幻灯片一起抄录了演讲文本。它通过一些图表更逐步地介绍了这些概念。float x[]
和float y[]
,因此您可以一次在x[i + 0..3]
,y[i + 0..3]
和x[j + 0..3]
,y[j + 0..3]
之间进行四个点积的完整SIMD向量。