2013-10-04 48 views
1

我想,以減少儘可能執行時間,以優化一些代碼。 這是代碼:如何使用ARM NEON優化此代碼?

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。 這可能嗎? 謝謝

編輯:此代碼的上下文是輕快的特點探測器(http://www.asl.ethz.ch/people/lestefan/personal/BRISK) 我試圖優化這個代碼的ARM架構。 的一段代碼我指的是具有以下結構:

-an外部爲週期,其掃描一定數量的點

- 對於這些點中的每一個有一定數目的其它點的周圍它(一個固定的數字),每一個都有一個相關的強度值。

-in內部爲點的週期固定對它們的強度值的基礎上進行比較,並且該比較的結果可以是0或1,並且該值被置於在載體中。

我張貼在這裏的代碼是內部的循環。

+0

我不是要求代碼,我只是想了解是否有方法通過NEON優化原始代碼。因爲我不是NEON專家,所以我甚至不知道我在問什麼是可能的。如果是這樣,我會自己實現它。我需要的只是關於可行性的一般性建議。 – user2696208

+0

如果沒有上下文/可編譯代碼,我現在可以建議的唯一事情就是向編譯器暗示這應該是向量化的/將從矢量化中受益。有關選項,請參閱http://stackoverflow.com/questions/14256156/how-to-give-hint-to-gcc-about-loop-count。 –

+1

我編輯了答案,增加了更多的上下文。 – user2696208

回答

3

編輯:最初我誤解了原來的源代碼。 這裏是正確的版本,完全重寫。 (55個週期/迭代)

雖然它不像以前的初始版本那樣容易,但NEON可以很好地處理這個問題,與原始的C實現相比,性能提升令人eye目。

通過正確的調整,您可能會獲得額外的性能提升(少於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的小菜一碟。

這是你的 「奇蹟」:

原型: 無效yourFunc(unsigned int類型* pPair,無符號整型* PTR2,無符號整型數);

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 

上面的代碼只是適度優化(在這裏和那裏聯鎖),並且只能當計數的32

多這是據我去管理可讀性和工作「不專業」的時候。

47週期/迭代不壞。其餘的由你決定。

祝你好運!

+0

謝謝!我真的很想了解現在的代碼,然後嘗試一下。這些說明是否有很好的手冊? – user2696208

+1

訪問我的博客armneon.blogspot.com除了我自己的教程之外,還有一些鏈接。 –

+0

@ user2696208我在誤解你的代碼時犯了一個嚴重的錯誤。我正在用「修訂」版本更新我的答案。 –