2012-01-24 4 views
3

は、コードは次です:アームループコードの最適化

for (int i=0; i<8; i++) { 
unsigned f = *p++; 
sum += f; 
sqsum += f*f; 
} 

私はいくつかのARMコードを作ったが、それは動作していない、でもコンパイルではありません次は何ですか:

void loop(uint8_t * p , int * sum ,int * qsum) 
{ 

__asm__ volatile("vld4.8 {d0}, [%0]!  \n" 
       "mov r4, #0    \n" 
       "vmlal.u8 [%1]!, [%1]!, d0 \n" 
       "vmull.u8 r4, d0 , d0 \n" 
       "vmlal.u8 [%2]!, [%2]!, r4\n" 
       : 
       : "r"(p), "r"(sum), "r"(qsum) 
       : "r4" 
       ); 



} 

助けが必要ですか?

void calculateMeanStDev8x8(cv::Mat* patch, int sx, int sy, int& mean, float& stdev) 
{ 

unsigned sum=0; 
unsigned sqsum=0; 

for (int j=0; j< 8; j++) { 
    const unsigned char* p = (const unsigned char*)(patch->data + (j+sy)*patch->step + sx); //Apuntador al inicio de la matrix 

    //The code to improve 
    for (int i=0; i<8; i++) { 
    unsigned f = *p++; 
sum += f; 
sqsum += f*f; 
} 

} 


mean = sum >> 6; 
int r = (sum*sum) >> 6; 
stdev = sqrtf(sqsum - r); 

if (stdev < .1) { 
    stdev=0; 
} 

}

+6

コンパイラが行うことができるループよりも手作業でループを最適化しようとしていることは間違いありません。コンパイラによって生成されたアセンブリを見たことがありますか? – zennehoy

+0

raw asmではなく、最初のインスタンスでこれにintrinsicsを使用したほうが効率的です。手作業で最適化されたasmで可能な限りパフォーマンスが向上します。 –

+1

@zennehoy実際には、これが本当の最適化として明らかになる可能性は非常に高いです。しかし、もう一度、あなたはOPが結果をコンパイラが生成するものと比較すべきであるというのはまったく正しいです。スタートのために、私はNEONの本能で遊ぶだろう。 – Till

答えて

3

をループはNEONの最適化のための完璧な候補であること:ここでは

が改善する私の機能です。 8つの符号なし整数を単一のNEONレジスタに収めることができます。 "vectorのすべての要素を合計する"命令はありませんが、pairwise addを使用して8つの要素の合計を3つのステップで計算することができます。アプリケーションの残りの部分を見ることができないので、大きな画像が何であるかを知るのは難しいですが、NEONはスピードを改善するための最善の策です。最近のApple製品はすべてNEON命令をサポートしており、XCodeではC++コードと混在したNEON組み込み関数を使用できます。

+0

私は今質問を編集しているので、あなたは今機能を知ることができます。ありがとう! – Gustavo