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
  • 为什么在数据未签名时进行签名操作?
  • 为什么要两次读取相同的数据?
  • 您的 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) : 
              );    
}

虽然看起来非常短并且似乎已经过优化,但这个霓虹灯版本不会更快(甚至更慢),因为:

  • 管道几乎每一步都互锁
  • “vmov r0,s0”(11 个周期)之前的一个巨大的打嗝

在这种情况下,我建议您坚持使用原始 C 代码。

于 2012-03-19T06:04:32.100 回答