gpt4 book ai didi

gcc - ARM GCC 错误?使用 vldr 链而不是一个 vldmia…

转载 作者:行者123 更新时间:2023-12-02 16:00:39 26 4
gpt4 key购买 nike

考虑以下 NEON 优化函数:

void mat44_multiply_neon(float32x4x4_t& result, const float32x4x4_t& a, const float32x4x4_t& b) {
// Make sure "a" is mapped to registers in the d0-d15 range,
// as requested by NEON multiply operations below:
register float32x4_t a0 asm("q0") = a.val[0];
register float32x4_t a1 asm("q1") = a.val[1];
register float32x4_t a2 asm("q2") = a.val[2];
register float32x4_t a3 asm("q3") = a.val[3];
asm volatile (
"\n\t# multiply two matrices...\n\t"
"# result (%q0,%q1,%q2,%q3) = first column of B (%q4) * first row of A (q0-q3)\n\t"
"vmul.f32 %q0, %q4, %e8[0]\n\t"
"vmul.f32 %q1, %q4, %e9[0]\n\t"
"vmul.f32 %q2, %q4, %e10[0]\n\t"
"vmul.f32 %q3, %q4, %e11[0]\n\t"
"# result (%q0,%q1,%q2,%q3) += second column of B (%q5) * second row of A (q0-q3)\n\t"
"vmla.f32 %q0, %q5, %e8[1]\n\t"
"vmla.f32 %q1, %q5, %e9[1]\n\t"
"vmla.f32 %q2, %q5, %e10[1]\n\t"
"vmla.f32 %q3, %q5, %e11[1]\n\t"
"# result (%q0,%q1,%q2,%q3) += third column of B (%q6) * third row of A (q0-q3)\n\t"
"vmla.f32 %q0, %q6, %f8[0]\n\t"
"vmla.f32 %q1, %q6, %f9[0]\n\t"
"vmla.f32 %q2, %q6, %f10[0]\n\t"
"vmla.f32 %q3, %q6, %f11[0]\n\t"
"# result (%q0,%q1,%q2,%q3) += last column of B (%q7) * last row of A (q0-q3)\n\t"
"vmla.f32 %q0, %q7, %f8[1]\n\t"
"vmla.f32 %q1, %q7, %f9[1]\n\t"
"vmla.f32 %q2, %q7, %f10[1]\n\t"
"vmla.f32 %q3, %q7, %f11[1]\n\t\n\t"
: "=&w" (result.val[0]), "=&w" (result.val[1]), "=&w" (result.val[2]), "=&w" (result.val[3])
: "w" (b.val[0]), "w" (b.val[1]), "w" (b.val[2]), "w" (b.val[3]),
"w" (a0), "w" (a1), "w" (a2), "w" (a3)
:
);
}

为什么 GCC 4.5 在加载第一个矩阵时会产生这种令人厌恶的现象:

vldmia  r1, {d0-d1}
vldr d2, [r1, #16]
vldr d3, [r1, #24]
vldr d4, [r1, #32]
vldr d5, [r1, #40]
vldr d6, [r1, #48]
vldr d7, [r1, #56]

...而不仅仅是:

vldmia  r1, {q0-q3}

…?

我使用的选项:

arm-none-eabi-gcc-4.5.1 -x c++ -march=armv7-a -mcpu=cortex-a8 -mfpu=neon -mfloat-abi=softfp -O3 -ffast-math -fgcse-las -funsafe-loop-optimizations -fsee -fomit-frame-pointer -fstrict-aliasing -ftree-vectorize

请注意,使用 iPhoneOS 提供的编译器会产生相同的结果:

/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/gcc-4.2 -x c++ -arch armv7 -mcpu=cortex-a8 -mfpu=neon -mfloat-abi=softfp -O3 -ffast-math -fgcse-las -funsafe-loop-optimizations -fsee -fomit-frame-pointer -fstrict-aliasing -ftree-vectorize

最佳答案

简单回答:

GCC 编译器目前不太擅长生成 ARM 代码。如果你仔细观察其他代码,你会发现 GCC 几乎从不安排寄存器,它可以使用多个寄存器加载/存储,除了像函数 prolog/epilog 和内联 memcpy 这样的硬编码位置。

当涉及到 Neon 指令的使用时,代码变得更糟。这与 NEON 单元的工作方式有关:您可以将寄存器对视为四双字或双双字。 (据我所知)这是 GCC 支持的体系结构中寄存器使用的一个独特功能。因此,代码生成器不会在所有情况下生成最佳代码。

顺便说一句:当我这样做时:GCC 不知道在 Cortex-A8 上使用“自由”桶形移位器功能会对寄存器调度产生重要影响,并且 GCC 大部分都是错误的。

关于gcc - ARM GCC 错误?使用 vldr 链而不是一个 vldmia…,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4525258/

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