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) : 
              );    
}

どうもありがとう!!!

4

2 に答える 2

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を手書きするのではなく、標準のメソッド呼び出しでこれを行うための便利な機能がたくさんあります。

于 2012-02-21T17:57:07.950 に答える
0
  • データが署名されていないのになぜ署名された操作なのですか?
  • なぜ同じデータを2回読み取るのですか?
  • Cコードの入力データは8ビットですが、ネオンコードの入力データは32ビットです。

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) : 
              );    
}

見た目は非常に短く、最適化されているように見えますが、このネオンバージョンは次の理由でそれほど速くはありません(またはさらに遅くなります)。

  • パイプラインはほぼすべてのステップでインターロックします
  • 「vmovr0、s0」の前の大きな問題(11サイクル)

この場合、元のCコードを使用することをお勧めします。

于 2012-03-19T06:04:32.100 に答える