x86_64 ARM64固有的点向量积

时间:2018-08-02 14:30:06

标签: assembly vectorization sse arm64

我正在将一个包含x86_64内在函数的小型C例程移植到ARM64平台。我找不到_mm_dp_pd的等效ARM64内在函数。

我确实可以使用手臂霓虹灯内部函数。

我不确定如何用等效的ARM64替换x86_64内在函数。

任何帮助将不胜感激。

#ifdef ARM64
    float32x4_t a, b;
#else
    __m128d a, b;
#endif

#ifdef ARM64
    ????
#else
    res = _mm_dp_pd(a, b, mask);
#endif

1 个答案:

答案 0 :(得分:0)

dppd的速度并不比垂直乘/洗/加的速度快,并且实际上在Intel CPU(https://agner.org/optimize/)上解码为3 oups可能做到了这一点(也许还有一些额外的好处)为面具)。

例如在Skylake上,它的延迟为9c,p01(FMA单元所在的位置)的延迟为2uop,p5(shuffle单元所在的位置)的延迟为1uop。

在Ryzen之前的AMD上它甚至更慢(例如Steamroller上为7微秒),但是Ryzen将其解码为3微秒。 (dpps仍然很慢,以防万一,您实际上想要四个32位float元素(float32x4_t)而不是两个64位double元素({{1 }})。


无论如何,假设您希望将点积结果广播到__m128d向量的两个元素上,请进行垂直乘法,然后交换一个向量并进行垂直加法。

将其移植到ARM应该很容易

double

或者,如果您只关心低元素,则可以使用更简单的随机播放,例如__m128d prods = _mm_mul_pd(a,b); __m128d swap = _mm_shuffle_pd(prods,prods, 0b01); __m128d dot = _mm_add_pd(prods, swap); Fastest way to do horizontal float vector sum on x86)。

如果您需要将上位元素清零,例如movhlps,那么可能需要在AArch64上附加一条指令。


顺便说一句,顺便说一句,如果您要执行大量DPPD,则可能需要考虑将数据布局更改为数组结构,因此可以并行执行两个点积而无需进行任何改组, mul和FMA。请参阅https://deplinenoise.wordpress.com/2015/03/06/slides-simd-at-insomniac-games-gdc-2015/,以获得有关将数据布局/整个方法设计为SIMD友好的良好解释

但是内循环之外的水平东西并不总是坏的。