2

私がコンパイルしているのarmv7は、NEONの積和演算の組み込み関数が、別々の積和と加算に分解されているように見えます。

これは、最新の4.5までのXcodeのいくつかのバージョン、iOS SDK 5〜6、およびXcodeとコマンドラインの両方を介して直接構築するさまざまな最適化設定で経験しました。

たとえば、いくつかtest.cppを含むものを構築および分解します

#include <arm_neon.h>

float32x4_t test( float32x4_t a, float32x4_t b, float32x4_t c )
{
   float32x4_t result = a;
   result = vmlaq_f32( result, b, c );
   return result;
}

clang++ -c -O3 -arch armv7 -o "test.o" test.cpp
otool -arch armv7 -tv test.o

結果は

test.o:
(__TEXT,__text) section
__Z4test19__simd128_float32_tS_S_:
00000000    f10d0910    add.w   r9, sp, #16 @ 0x10
00000004        46ec    mov ip, sp
00000006    ecdc2b04    vldmia  ip, {d18-d19}
0000000a    ecd90b04    vldmia  r9, {d16-d17}
0000000e    ff420df0    vmul.f32    q8, q9, q8
00000012    ec432b33    vmov    d19, r2, r3
00000016    ec410b32    vmov    d18, r0, r1
0000001a    ef400de2    vadd.f32    q8, q8, q9
0000001e    ec510b30    vmov    r0, r1, d16
00000022    ec532b31    vmov    r2, r3, d17
00000026        4770    bx  lr

の予想される使用の代わりにvmla.f32

何が間違っているのですか?

4

2 に答える 2

3

これはバグか、llvm-clangによる最適化のいずれかです。armccまたはgccは期待どおりにvmlaを生成しますが、Cortex-Aシリーズプログラマーズガイドv3を読むと、次のようになります。

20.2.3スケジューリング

場合によっては、特にVMLA積和演算(整数の場合は5サイクル、浮動小数点の場合は7サイクル)など、かなりの遅延が発生する可能性があります。これらの命令を使用するコードは、準備が整う前に結果値を使用しようとしないように最適化する必要があります。そうしないと、ストールが発生します。結果としてレイテンシが数サイクルあるにもかかわらず、これらの命令は完全にパイプライン処理されるため、一度に複数の操作を実行できます。

したがって、llvm-clangがvmlaを乗算に分離し、パイプラインを満たすために累積することは理にかなっています。

于 2012-10-18T21:16:15.037 に答える
1

ネオン乗算-加算命令は操作を実行します

c = c + a * b

宛先とソースの1つが同じであることに注意してください。操作を実行したい場合

d = c + a * b

コンパイラはそれを2つの命令に分解する必要があります

d = c
d = d + a * b

別の方法として、乗算+命令の追加に分解できます

d = a * b
d = d + c

Cortex-A8 / A9では、両方のバリアントのスループットは同じですが、Cortex-A8では、乗算加算命令によって多くの状況でストールが発生するため、2番目のバリアントのレイテンシは低くなります。

于 2012-10-17T20:37:23.830 に答える