2

VFP Android デバイスで ARMv6 をターゲットにしたいと考えています。

Android.mk有効にするためにファイルに次の行がありますVFP

LOCAL_CFLAGS    := -marm -mfloat-abi=softfp -mfpu=vfp -Wmultichar

をターゲットにARMv5していると思いVFPます。

android-ndk-r8b\toolchains\arm-linux-androideabi-4.6\setup.mk削除するように編集しました-msoft-float。オリジナルもやってみたsetup.mk

私のコードは 99.99% の確率で正常に動作しますが、ARMv6 デバイスではおかしくなることがあります。私はそれがいつ狂ったかを検出する特別なコードを持っています。

コード

glm::vec3 D = P1 - P2;
float f1 = sqrtf(D.x*D.x + D.y*D.y + D.z*D.z);
if(!(f1 < 5)){
    // f1 is bigger then 5 or NaN
    mylog_fmt("Crazy %f %f %f %f", P1.x, P1.y, P1.z, f1);
    mylog_fmt("%f %f %f", P2.x, P2.y, P2.z);
}

LogCat :

12-14 00:59:08.214: I/APP(17091): Crazy -20.000031 0.000000 0.000000 20.000000
12-14 00:59:08.214: I/APP(17091): -20.000000 0.000000 0.000000

2 点間の距離を計算します。通常は 0.000031crazy modeですが、オンの場合は 20.0 です。

ARMv7 CPU で実行すると、問題は発生しません。ARMv6 CPU にのみ存在します。

コンパイラの設定またはバージョンに関連する一般的な既知のバグであると思います。コードにメモリ バリアがない可能性があります。

同様のバグへの参照をいくつか見たいと思います。それを解決する方法。またはバグの性質について。

また、ARMv7 の同じコードで NaN が返されない場合でも、ARMv6 で NaN 値を取得することがよくあります。

私はすでに 2 週間コードをデバッグしており、Web を検索しています。誰かが同様の問題へのリンクを共有できれば、それは大きな助けになるでしょう!

PS。コンパイル コマンドの 1 つの例を次に示します。すでにさまざまな設定を試しました。

コンパイラの設定

c:/soft/Android/android-ndk-r8b/toolchains/arm-linux-androideabi-4.6/prebuilt/windows/bin/arm-linux-androideabi-g++
-MMD -MP -MF ./obj/local/armeabi/objs/main/sys/base.o.d -fpic -ffunction-sections -funwind-tables -fstack-protector 
-D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__
-D__ARM_ARCH_5TE__  
-march=armv5te -mtune=arm6 
-mfloat-abi=softfp -mfpu=vfp
-fno-exceptions -fno-rtti -mthumb -Os -fomit-frame-pointer -fno-strict-aliasing -finline-limit=64 
-Ijni/main/ -Ijni/main/sys -Ijni/main/bullet/src -Ijni/main/bullet/src/LinearMath -Ijni/main/bullet/src/BulletCollision/BroadphaseCollision 
-Ijni/main/bullet/src/BulletCollision/CollisionDispatch -Ijni/main/bullet/src/BulletCollision/CollisionShapes -Ijni/main/bullet/src/BulletCollision/NarrowPhaseCollision 
-Ijni/main/bullet/src/BulletDynamics/ConstraintSolver -Ijni/main/bullet/src/BulletDynamics/Dynamics -Ijni/main/../libzip/ -Ic:/soft/Android/android-ndk-r8b/sources/cxx-stl/stlport/stlport 
-Ic:/soft/Android/android-ndk-r8b/sources/cxx-stl//gabi++/include -Ijni/main 
-DANDROID

-marm -march=armv6 -mfloat-abi=softfp -mfpu=vfp -Wmultichar

-Wa,--noexecstack  -frtti  -O2 -DNDEBUG -g   -Ic:/soft/Android/android-ndk-r8b/platforms/android-5/arch-arm/usr/include -c  jni/main/sys/base.cpp
-o ./obj/local/armeabi/objs/main/sys/base.o

更新 2

これらのデバイスはすべて Qualcomm MSM7227A を搭載しており、ARM1136JF-S を搭載しています。

私がこれまでに学んだことは、デフォルトでゼロにフラッシュされ、ARM1136SF-S がオプションでそれを de-norms 持っている ARMv6 と ARMv7 の違いをどこかで読むことにバグが関連している可能性があるということです。http://infocenter.arm.com/help/topic/com.arm.doc.ddi0211k/DDI0211K_arm1136_r1p5_trm.pdfdenorms

ARM で Flush-To-ZERO フラグを確認する方法がまだわかりません。

更新 3

この CPU の VFP はVFP11 I found--vfp11-denorm-fixオプションと呼ばれます。また、CPU--vfp-denorm-fix の正誤表も修正されてVFP11います。私のターゲットの問題のように見えます。VFP11 エラッタに関する投稿がほとんど見つかりませんでした。コードが修正されることを願っています。

4

2 に答える 2

2

バグを特定したようです。

VFP11 (ARMv6 コプロセッサ) denorm バグのバグです。 非正規数は非常に小さい数です。

ダンピングを使用してスプリングを実装する物理コードでこの数値を取得します

force1 = (Center - P1) * k1         // force1 directed to center 
force2 = - Velocity * k2            // force2 directed against velocity
Object->applyForce(force1)
Object->applyForce(force2)

オブジェクトがアーカイブされると、両方の力が非常に小さくなり、最後に値がCenter得られます。denormal

sring とダンピングを書き直すことはできますが、穴の BulletPhysics やすべての数学コードを書き直したり、非正規数のすべての (内部であっても) 発生を予測することはできません。

リンカには修正コード オプション--vfp11-denorm-fix--vfp-denorm-fix http://sourceware.org/binutils/docs-2.19/ld/ARM.htmlがあります

NDK リンカーには、--vfp11-denorm-fix このオプションが役立ちます。コードはより信頼できるように見えますが、問題を 100% 修正するわけではありません。

バグが少なくなりました。

しかし、オブジェクトを安定化させるのを待つと、最終的に denorm を取得します -> NaN

もっと長く待たなければなりませんが、同じ問題が発生します。

コードを修正するソリューションを知っている場合は--vfp11-denorm-fix、報奨金を差し上げます。

--vfp11-denorm-fix=scalar私は両方を試しました--vfp11-denorm-fix=vector

ゼロビットにフラッシュ

      int x;
      // compiles in ARM mode
      asm(
              "vmrs %[result],FPSCR \r\n"
              "orr %[result],%[result],#16777216 \r\n"
              "vmsr FPSCR,%[result]"
              :[result] "=r" (x) : :
      );

理由はわかりませんが、必要なだけではなく 5月に必要LOCAL_ARM_MODE := armです。Android.mk-mfpu=vfp-d16vfp

手動で非正規数をクリアする

上記のスプリングコードがあります。以下の機能を持つFPUを使わず手動でデノーマル数をクリアすることで改善しました。

inline void fixDenorm(float & f){
    union FloatInt32 {
        unsigned int u32;
        float f32;
    };
        FloatInt32 fi;
        fi.f32 = f;

        unsigned int exponent = (fi.u32 >> 23) & ((1 << 8) - 1);
        if(exponent == 0)
            f = 0.f;
}

元のコードは、多くの場所で開始から 15 ~ 90 秒で失敗していました。

現在のコードでは、10 分間の物理シミュレーションを行った後、このバグに関連する可能性のある問題が 1 つの場所にのみ示されました。


バグと修正への 参照 http://sourceware.org/ml/binutils/2006-12/msg00196.html

GCCscalr コードだけで十分だと言われています--vfp11-denorm-fix=scalar。減速するためのコマンドが 1 つ追加されます。しかし、それでも--vfp11-denorm-fix=vector2 つのコマンドを追加するだけでは十分ではありません。

問題は簡単には再現できません。周波数が高い 800Mhz の電話では、600Mhz の遅い電話よりも頻繁に見られます。市場に高速な CPU がなかったときに修正が行われた可能性があります。


プロジェクトには多くのファイルがあり、すべての構成のコンパイルには約 10 分かかります。現在の修正状態でのテストでは、電話で再生するのに約 10 分かかります。+ランプの下で電話を加熱します。ホットフォンはエラーをより速く表示します。

さまざまな構成をテストし、どの修正が最も効率的かを報告したいと考えています。しかし今は、おそらく非標準に関連する最後のバグを殺すためにハックを追加する必要があります。

私はそれを修正する特効薬を見つけることを期待していましたが、-msoft-floatパフォーマンスが 10 倍低下するか、ARMv7 でアプリを実行している場合にのみ修正されます。


以前のfixDenorm関数をfixDenormE春/ダンピングコードの新しい関数に置き換え、ViewMatrix に新しい関数を適用した後、最後のバグを取り除きました。

inline void fixDenormE(float & f, float epsilon = 1e-8){
    union Data32 {
        unsigned int u32;
        float f32;
    };
        Data32 d;
        d.f32 = f;

        unsigned int exponent = (d.u32 >> 23) & ((1 << 8) - 1);
        if(exponent == 0)
            f = 0.f;
        if(fabsf(f) < epsilon){
          f = 0.f;
        }
}
于 2012-12-18T23:12:19.887 に答える
0

このページには、ARM FPU オプションに関する興味深い議論があります: VfpComparison

ARM v6 用にビルドする場合は、次のようにするとよいと思います-march=armv6 -mcpu=generic-armv6 -mfloat-abi=softfp(-mfpu オプションは省略します)。上記のプロセッサを特に対象としていない場合、汎用の armv6 には保証された fpu がありません。

別のオプションは-mfloat-abi=hard、softfp のどこかにコンパイラのバグがあるという理論に基づいて、 を試すことです。

また、コード内のスタックの破損なども確認してください。浮動小数点値が渡されると、それらが破壊される可能性があります。

PS また、 TestFloatや由緒ある netlib paranoiaなどの浮動小数点テスターを試してみることもできます。この特定のプロセッサとこれらのコンパイラ オプションで浮動小数点が失敗する例がありますが、それがどれほど広範囲に及ぶ問題かはわかりません。あなたが思っているよりも悪いかもしれません:)

于 2012-12-18T20:33:31.013 に答える