10

OpenCVforを使用してコンピューティング集中型アプリを実行しましたiOS。もちろん遅かったです。しかし、それは私のPCプロトタイプよりも200倍遅いものでした。だから私はそれを最適化していました。最初の15秒から0.4秒の速度を得ることができました。私はすべてのものを見つけたのだろうか、そして他の人が共有したいと思うかもしれないものを見つけたのだろうか。私がしたこと:

  1. doubleOpenCV内の""データ型を""に置き換えましfloatた。Doubleは64ビットで32ビットCPUはそれらを簡単に処理できないので、floatは私にある程度の速度を与えました。OpenCVはdoubleを非常に頻繁に使用します。

  2. -mpfu=neonコンパイラオプションに「」を追加しました。副作用は、エミュレータコンパイラが機能しなくなり、ネイティブハードウェアでのみテストできるという新しい問題でした。

  3. 90個の値のルックアップテーブルに置き換えられsin()、実装されました。cos()スピードアップはすごかった!これは、そのような最適化がスピードアップをもたらさないPCとはやや反対です。度で動作するコードがあり、この値はとのラジアンに変換されましsin()cos()。このコードも削除されました。しかし、ルックアップテーブルがその役割を果たしました。

  4. 有効"thumb optimizations"。いくつかのブログ投稿は正反対を推奨していますが、これは親指が通常物事を遅くするためarmv6です。armv7問題がなく、物事をより速く、より小さくします。

  5. 親指の最適化を確実-mfpu=neonにし、最高の状態で機能し、クラッシュを引き起こさないようにするために、armv6ターゲットを完全に削除しました。私のコードはすべてコンパイルされてarmv7おり、これもアプリストアの要件としてリストされています。これは、最小値iPhoneがになることを意味します3GS。古いものを落としても大丈夫だと思います。とにかく古いものはCPUが遅く、CPUを集中的に使用するアプリは、古いデバイスにインストールするとユーザーエクスペリエンスが低下します。

  6. もちろん使用します-O3 flag

  7. "dead code"OpenCVから削除しました。OpenCVを最適化するときに、プロジェクトに明らかに必要のないコードが表示されることがよくあります。たとえば、多くの場合"if()"、ピクセルサイズが8ビットまたは32ビットであることを確認するための追加機能があり、8ビットのみが必要であることがわかっています。これにより、一部のコードが削除され、オプティマイザーがさらに何かを削除したり、定数に置き換えたりする機会が増えます。また、コードはキャッシュによりよく適合します。

他のトリックやアイデアはありますか?私にとって、親指を有効にし、三角法をルックアップに置き換えることは、ブーストメーカーであり、私を驚かせました。たぶん、アプリを飛ばすためにもっとや​​るべきことを知っていますか?

4

2 に答える 2

13

多くの浮動小数点計算を行う場合は、AppleのAccelerateフレームワークを使用すると非常に役立ちます。浮動小数点ハードウェアを使用して、ベクトルの計算を並列に実行するように設計されています。

また、あなたのポイントを1つずつ取り上げます。

1)これはCPUのせいではなく、armv7時代の時点で、32ビット浮動小数点演算のみが浮動小数点プロセッサハードウェアで計算されるためです(アップルがハードウェアを置き換えたため)。64ビットのものは代わりにソフトウェアで計算されます。代わりに、32ビット演算がはるかに高速になりました。

2)NEONは、新しい浮動小数点プロセッサ命令セットの名前です。

3)はい、これはよく知られている方法です。別の方法は、私が上で述べたAppleのフレームワークを使用することです。これは、4つの値を並行して計算するsin関数とcos関数を提供します。アルゴリズムはアセンブリとNEONで微調整されているため、最小限のバッテリーを使用しながら最大のパフォーマンスを発揮します。

4)thumbの新しいarmv7実装には、armv6の欠点はありません。無効化の推奨事項はv6にのみ適用されます。

5)はい、ユーザーの80%が現在iOS 5.0以降を使用していることを考えると(armv6デバイスは4.2.1でサポートを終了しました)、これはほとんどの状況で完全に受け入れられます。

6)これは、リリースモードでビルドすると自動的に行われます。

7)はい、ただし、これは上記の方法ほど大きな効果はありません。

Accelerateをチェックすることをお勧めします。そうすれば、浮動小数点プロセッサの能力をフルに活用していることを確認できます。

于 2012-06-27T04:22:54.657 に答える
1

以前の投稿にフィードバックを提供します。これは、ポイント7でデッドコードについて提供しようとしたいくつかのアイデアを説明しています。これは、少し広いアイデアを意味していました。フォーマットが必要なので、コメントフォームは使用できません。そのようなコードはOpenCVにありました:

for( kk = 0; kk < (int)(descriptors->elem_size/sizeof(vec[0])); kk++ ) {
    vec[kk] = 0;
}

組み立て時にどのように見えるかを見たかったのです。アセンブリで確実に見つけられるように、次のようにラップしました。

__asm__("#start");
for( kk = 0; kk < (int)(descriptors->elem_size/sizeof(vec[0])); kk++ ) {
    vec[kk] = 0;
}
__asm__("#stop");

ここで、[製品]->[出力の生成]->[アセンブリファイル]を押すと、次のようになります。

    @ InlineAsm Start
    #start
    @ InlineAsm End
Ltmp1915:
    ldr r0, [sp, #84]
    movs    r1, #0
    ldr r0, [r0, #16]
    ldr r0, [r0, #28]
    cmp r0, #4
    mov r0, r4
    blo LBB14_71
LBB14_70:
Ltmp1916:
    ldr r3, [sp, #84]
    movs    r2, #0
Ltmp1917:
    str r2, [r0], #4
    adds    r1, #1
Ltmp1918:
Ltmp1919:
    ldr r2, [r3, #16]
    ldr r2, [r2, #28]
    lsrs    r2, r2, #2
    cmp r2, r1
    bgt LBB14_70
LBB14_71:
Ltmp1920:
    add.w   r0, r4, #8
    @ InlineAsm Start
    #stop
    @ InlineAsm End

たくさんのコード。の値をprintf-dして、(int)(descriptors->elem_size/sizeof(vec[0]))常に64でした。そこで、64にハードコーディングし、アセンブラーを介して再度渡しました。

    @ InlineAsm Start
    #start
    @ InlineAsm End
Ltmp1915:
    vldr.32 s16, LCPI14_7
    mov r0, r4
    movs    r1, #0
    mov.w   r2, #256
    blx _memset
    @ InlineAsm Start
    #stop
    @ InlineAsm End

ご覧のとおり、オプティマイザーがアイデアを思いつき、コードがはるかに短くなりました。これをベクトル化することができました。ポイントは、これがWebカメラのカメラサイズやピクセル深度のようなものである場合、コンパイラは常にどの入力が定数であるかを知らないということですが、実際には私のコンテキストでは通常一定であり、私が気にするのは速度だけです。

また、3行を次のように置き換えることを提案したAccelerateも試しました。

__asm__("#start");
vDSP_vclr(vec,1,64);
__asm__("#stop");

アセンブリは次のようになります。

    @ InlineAsm Start
    #start
    @ InlineAsm End
Ltmp1917:
    str r1, [r7, #-140]
Ltmp1459:
Ltmp1918:
    movs    r1, #1
    movs    r2, #64
    blx _vDSP_vclr
Ltmp1460:
Ltmp1919:
    add.w   r0, r4, #8
    @ InlineAsm Start
    #stop
    @ InlineAsm End

ただし、これがbzeroよりも速いかどうかはわかりません。私の文脈では、この部分はあまり時間がかからず、2つのバリアントが同じ速度で動作しているように見えました。

私が学んだもう1つのことは、GPUの使用です。詳細はこちらhttp://www.sunsetlakesoftware.com/2012/02/12/introducing-gpuimage-framework

于 2012-07-03T08:35:21.960 に答える