2012-02-21 16 views
1

私はいくつかのコードを改善しようとしましたが、できませんでしたのでここで助けを求めます。また、組み込み関数で試しましたが、組み込み関数を使用するにはGCCコンパイラを使用する必要があります。このコンパイラはLLVMよりも低速のコードをコンパイルしますが、すべてのコードが遅くなります。そのため、最適なオプションは直接asmを使用することです。 私は両方の機能を私が改善したい、ネオンのコードに入れて、コードはナンセンスの数字を返しています。 私は本当にこれで助けが必要です、正しい方向への任意のポイントは私をたくさん助けることができます。ネオンで改善するコード

私は改善したいコード:

inline unsigned des(const unsigned char* v0) 
{ 
unsigned r; 
r = v0[0]*v0[0]; 
r += v0[1]*v0[1]; 
r += v0[2]*v0[2]; 
r += v0[3]*v0[3]; 
r += v0[4]*v0[4]; 
r += v0[5]*v0[5]; 
r += v0[6]*v0[6]; 
r += v0[7]*v0[7]; 
return r; 
} 


inline unsigned suma(const unsigned char* v0) 
{ 
unsigned r; 
r = v0[0]; 
r += v0[1]; 
r += v0[2]; 
r += v0[3]; 
r += v0[4]; 
r += v0[5]; 
r += v0[6]; 
r += v0[7]; 
return r; 
} 

ネオンコードが

unsigned desneon(unsigned v0[8]) 
{ 
asm volatile (
       "vld1.32  {d2- d5}, [%0]   \n\t" 
       "vld1.32  {d6- d9}, [%0]   \n\t" 
       "vmul.s32   d0, d2, d6    \n\t" //d0= d2*d6 
       "vmla.s32   d0, d3, d7    \n\t" //d0 = d0 + d3*d7 
       "vmla.s32  d0, d4, d8    \n\t" //d0 = d0 + d4*d8 
       "vmla.s32  d0, d5, d9    \n\t" //d0 = d0 + d5*d9 
      "vpadd.s32   d0, d0     \n\t" //d0 = d[0] + d[1] 


       :: "r"(v0) : 
      );  
} 

おかげでたくさん働いていません!

+1

あなたは実際にそのメソッドから何も返されていません。 'd0'はあなたが望む結果で終わりますが、実際には返す必要があります。 – mattjgalloway

+1

Accelerate.frameworkでvDSP関数を使用しないのはなぜですか? – Nyx0uf

+0

vDSPは浮動小数点数を使用していますが、これによりアプリケーションが遅くなると思いますか? – Gustavo

答えて

2

実際に値を返す必要があります。私はあなたがこのようなことをしたいと思う:

unsigned desneon(unsigned v0[8]) 
{ 
    unsigned outlo; 
    __asm__ volatile (
         "vld1.32  {d2- d5}, [%1]   \n\t" 
         "vld1.32  {d6- d9}, [%1]   \n\t" 
         "vmul.s32  d0, d2, d6    \n\t" //d0= d2*d6 
         "vmla.s32  d0, d3, d7    \n\t" //d0 = d0 + d3*d7 
         "vmla.s32  d0, d4, d8    \n\t" //d0 = d0 + d4*d8 
         "vmla.s32  d0, d5, d9    \n\t" //d0 = d0 + d5*d9 
         "vpadd.s32 d0, d0     \n\t" //d0 = d[0] + d[1] 
         "vmov   %0, r4, d0    \n\t" 
         :"=r"(outlo) 
         :"r"(v0) 
         :"d0", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "r4" 
        ); 
    return outlo; 
} 

私は正しい結果を与えてくれたようだ。 @ Nyx0ufが述べているように、Accelerateフレームワークを見てみたいと思うかもしれません.NEONを手書きするのではなく、標準のメソッド呼び出しでこれを行うのに便利なことがたくさんあります。

+0

ありがとう!!!私の視点からは、このフレームワークは常に浮動小数点を使用しているように見えますが、浮動小数点数を使って作業するとアプリケーションが遅くなります。 – Gustavo

+0

改善が少しでも遅いですが、上記の改善のコードを書いていますが、進化させるための実例がありますように感謝します。 – Gustavo

0
  • なぜデータが符号なしの操作で署名されたのですか?
  • なぜ同じデータを2回読みますか?
  • Cコードの入力データは8ビットですが、ネオンコードは32ビットです。

    unsigned desneon(unsigned v0[8]) 
    { 
    asm volatile (
          "vldmia  {q0-q1}, [%0]   \n\t" 
          "vmul.u32 q0, q0, q0    \n\t" 
          "vmla.u32 q0, q1, q1    \n\t" 
          "vpaddl.u32 q0, q0     \n\t"  
          "vadd.u64 d0, d0, d1    \n\t"  
          "vmov  r0, s0     \n\t"  
    
           :: "r"(v0) : 
          );  
    } 
    

    印象的なショートを見て、最適化されるように見えるが、このネオンのバージョンが原因でずっと速く(あるいは遅く)なりません:

    私はお勧め、32ビットの入力データを仮定し
  • "VMOV R0、S0"(11サイクル) 前にほとんどすべてのステップ

  • 巨大なしゃっくり
    • パイプラインインターロック

      この場合、オリジナルのCコードを使用することをお勧めします。

  • +0

    こんにちはジェイク、答えてくれてありがとう、私はこの行を変更する必要がありました "" vldmia%0、{q0-q1} \ n \ t ""、私はそれを実行すると、悪意を持っているように見える、何も、何も、何も、何も殺す、ないmem ...何も、何かプログラムカウンタに関連する何か、しかし私は問題を見つけることはありません。 – Gustavo

    +0

    最後の行vmovが原因である可能性があります。私はインラインアセンブリに慣れていません。 s0の値が返されるように変更してください。 –