gpt4 book ai didi

gcc - 有没有更有效的方法将4个连续的double广播到4个YMM寄存器中?

转载 作者:行者123 更新时间:2023-11-30 16:57:50 31 4
gpt4 key购买 nike

在一段类似于(但不完全)矩阵乘法的C ++代码中,我将4个连续的double加载到4个YMM寄存器中,如下所示:

# a is a 64-byte aligned array of double
__m256d b0 = _mm256_broadcast_sd(&b[4*k+0]);
__m256d b1 = _mm256_broadcast_sd(&b[4*k+1]);
__m256d b2 = _mm256_broadcast_sd(&b[4*k+2]);
__m256d b3 = _mm256_broadcast_sd(&b[4*k+3]);


我在Sandy Bridge机器上使用gcc-4.8.2编译了代码。硬件事件计数器(Intel PMU)建议CPU实际上从L1缓存中发出4个单独的负载。尽管此时我不受L1延迟或带宽的限制,但是我很感兴趣地想知道是否有一种方法可以用一个256位负载(或两个128位负载)加载4个double,然后将它们洗牌到4个YMM寄存器。我浏览了 Intel Intrinsics Guide,但找不到找到所需的改组方法。那可能吗?

(如果CPU不能合并4个连续负载的前提实际上是错误的,请告诉我。)

最佳答案

在我的matrix multiplication code中,每个内核代码只需要使用一次广播,但是如果您真的想在一条指令中加载四个双精度数,然后将它们广播到四个寄存器,您可以这样做

#include <stdio.h>
#include <immintrin.h>

int main() {
double in[] = {1,2,3,4};
double out[4];
__m256d x4 = _mm256_loadu_pd(in);
__m256d t1 = _mm256_permute2f128_pd(x4, x4, 0x0);
__m256d t2 = _mm256_permute2f128_pd(x4, x4, 0x11);
__m256d broad1 = _mm256_permute_pd(t1,0);
__m256d broad2 = _mm256_permute_pd(t1,0xf);
__m256d broad3 = _mm256_permute_pd(t2,0);
__m256d broad4 = _mm256_permute_pd(t2,0xf);

_mm256_storeu_pd(out,broad1);
printf("%f %f %f %f\n", out[0], out[1], out[2], out[3]);
_mm256_storeu_pd(out,broad2);
printf("%f %f %f %f\n", out[0], out[1], out[2], out[3]);
_mm256_storeu_pd(out,broad3);
printf("%f %f %f %f\n", out[0], out[1], out[2], out[3]);
_mm256_storeu_pd(out,broad4);
printf("%f %f %f %f\n", out[0], out[1], out[2], out[3]);
}


编辑:这是基于Paul R的建议的另一个解决方案。

__m256 t1 = _mm256_broadcast_pd((__m128d*)&b[4*k+0]);
__m256 t2 = _mm256_broadcast_pd((__m128d*)&b[4*k+2]);
__m256d broad1 = _mm256_permute_pd(t1,0);
__m256d broad2 = _mm256_permute_pd(t1,0xf);
__m256d broad3 = _mm256_permute_pd(t2,0);
__m256d broad4 = _mm256_permute_pd(t2,0xf);

关于gcc - 有没有更有效的方法将4个连续的double广播到4个YMM寄存器中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39296632/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com