1

可能な限り実行時間を短縮するために、いくつかのコードを最適化しようとしています。これはコードです:

    int shifter=0;

    // now iterate through all the pairings
    UINT32_ALIAS* ptr2=(UINT32_ALIAS*)ptr;
    const BriskShortPair* max=shortPairs_+noShortPairs_;
    for(BriskShortPair* iter=shortPairs_; iter<max;++iter){
        t1=*(_values+iter->i);
        t2=*(_values+iter->j);
        if(t1>t2){
            *ptr2|=((1)<<shifter);

        } // else already initialized with zero
        // take care of the iterators:
        ++shifter;
        if(shifter==32){
            shifter=0;
            ++ptr2;
        }
    }

NEONを使用してこれを何らかの方法で並列化できるかどうか疑問に思っていました。出来ますか?ありがとうございました

編集: このコードのコンテキストは、BRISK 機能検出器 ( http://www.asl.ethz.ch/people/lestefan/personal/BRISK ) です。このコードを ARM アーキテクチャ用に最適化しようとしています。私が参照しているコードは、次の構造を持っています。

- 特定の数のポイントをスキャンする外部 for サイクル

-これらのポイントのそれぞれに対して、その周りに特定の数の他のポイントがあり(固定数)、これらのそれぞれに強度値が関連付けられています。

- サイクルの内部では、ポイントの固定ペアが強度値に基づいて比較され、この比較の結果は 0 または 1 になり、この値はベクトルに入れられます。

ここに投稿したコードは、サイクルの内部です。

4

1 に答える 1

3

EDIT : 私は当初、元のソース コードを誤解していました。これは、完全に書き直された正しいバージョンです。(55 サイクル/反復)

以下の初期バージョンで想定されているほど簡単ではありませんが、NEON はこれを非常にうまく処理できるため、元の C 実装と比較して驚くほどパフォーマンスが向上します。

適切な調整を行うと、パフォーマンスがさらに向上する可能性があります (反復あたり 50 サイクル未満)。ただし、読みやすさは大きく損なわれます。

楽しむ!

    AREA    BRISK_ASM_NEON, CODE, READNOLY
    EXPORT  yourFunction
    CODE32

yourFunction    FUNCTION

loop
    pld     [r0, #192]
    vld2.32     {q8, q9}, [r0]!
    vld2.32     {q10, q11}, [r0]!
    pld     [r0, #192]
    vld2.32     {q12, q13}, [r0]!
    vld2.32     {q14, q15}, [r0]!

    vcgt.u32    q8, q8, q9
    vcgt.u32    q9, q10, q11
    vcgt.u32    q10, q12, q13
    vcgt.u32    q11, q14, q15

    pld     [r0, #192]
    vld2.32     {q12, q13}, [r0]!
    vld2.32     {q14, q15}, [r0]!
    pld     [r0, #192]
    vld2.32     {q0, q1}, [r0]!
    vld2.32     {q2, q3}, [r0]!

    vcgt.u32    q12, q12, q13
    vcgt.u32    q13, q14, q15
    vcgt.u32    q14, q0, q1
    vcgt.u32    q15, q2, q3

    vsli.32     q8, q10, #8
    vsli.32     q9, q11, #8
    vsli.32     q8, q12, #16
    vsli.32     q9, q13, #16
    vsli.32     q8, q14, #24
    vsli.32     q9, q15, #24

    vsli.8      d16, d17, #2
    vsli.8      d18, d19, #2
    vsli.8      d16, d18, #4

    vbic.i8     d16, #0xaa
    vshr.u64    d17, d16, #31
    vorr        d16, d16, d17

    vst1.32     {d16[0]}, [r1]!

    subs        r2, r2, #32
    bgt     loop

    bx  lr

    ENDFUNC
    END

================================================== ===========================

!!!!!!!! 以下のコードは無効です!!!!!!!!

================================================== ===========================

それはNEONとのケーキです。

これがあなたの「奇跡」です:

プロトタイプ: void yourFunc(unsigned int * pPair, unsigned int * ptr2, unsigned int count);

    AREA    BRISK_ASM_NEON, CODE, READNOLY
    EXPORT  yourFunction
    CODE32

yourFunction    FUNCTION
    adr r12, shifter_table
    vpush   {q4-q7}
    vldmia  r12, {q0-q7}

loop
    vld1.32 {q8, q9}, [r1]
    vorr    q10, q8, q0
    vorr    q11, q9, q1
    vld2.32 {q12, q13}, [r0]!
    vld2.32 {q14, q15}, [r0]!
    vcgt.u32    q12, q12, q13
    vcgt.u32    q13, q14, q15
    vbsl    q12, q10, q8
    vbsl    q13, q11, q9
    vst1.32 {q12, q13}, [r1]!

    vld1.32 {q8, q9}, [r1]
    vorr    q10, q8, q2
    vorr    q11, q9, q3
    vld2.32 {q12, q13}, [r0]!
    vld2.32 {q14, q15}, [r0]!
    vcgt.u32    q12, q12, q13
    vcgt.u32    q13, q14, q15
    vbsl    q12, q10, q8
    vbsl    q13, q11, q9
    vst1.32 {q12, q13}, [r1]!

    vld1.32 {q8, q9}, [r1]
    vorr    q10, q8, q4
    vorr    q11, q9, q5
    vld2.32 {q12, q13}, [r0]!
    vld2.32 {q14, q15}, [r0]!
    vcgt.u32    q12, q12, q13
    vcgt.u32    q13, q14, q15
    vbsl    q12, q10, q8
    vbsl    q13, q11, q9
    vst1.32 {q12, q13}, [r1]!

    vld1.32 {q8, q9}, [r1]
    vorr    q10, q8, q6
    vorr    q11, q9, q7
    vld2.32 {q12, q13}, [r0]!
    vld2.32 {q14, q15}, [r0]!
    vcgt.u32    q12, q12, q13
    vcgt.u32    q13, q14, q15
    vbsl    q12, q10, q8
    vbsl    q13, q11, q9
    vst1.32 {q12, q13}, [r1]!

    subs    r2, #32
    bgt loop

    vpop    {q4-q7}
    bx  lr

    ENDFUNC

shifter_table
    DCD (1<<00), (1<<01), (1<<02), (1<<03), (1<<04), (1<<05), (1<<06), (1<<07), (1<<08), (1<<09), (1<<10), (1<<11), (1<<12), (1<<13), (1<<14), (1<<15)
    DCD (1<<16), (1<<17), (1<<18), (1<<19), (1<<20), (1<<21), (1<<22), (1<<23), (1<<24), (1<<25), (1<<26), (1<<27), (1<<28), (1<<29), (1<<30), (1<<31)

    END

上記のコードは適度に最適化されており (あちこちでインターロック)、count が 32 の倍数の場合にのみ機能します。

それは、私が読みやすさを管理し、「専門外」に作業している場合です。

47サイクル/反復は悪くありません。後は君しだい。

幸運を!

于 2013-10-05T07:02:41.813 に答える