使用内在函数的霓虹灯优化

iti*_*avi 5 arm neon cortex-a8

了解ARM NEON内在函数,我正在计算一个函数,我编写的函数将数组中的元素加倍.使用内在函数的版本比函数的普通C版本花费更多时间.

没有NEON:

    void  double_elements(unsigned int *ptr, unsigned int size)
 {
        unsigned int loop;
        for( loop= 0; loop<size; loop++)
                ptr[loop]<<=1;
        return;
 }
Run Code Online (Sandbox Code Playgroud)

使用NEON:

 void  double_elements(unsigned int *ptr, unsigned int size)
{    
        unsigned int i;
        uint32x4_t Q0,vector128Output;
        for( i=0;i<(SIZE/4);i++)
        {
                Q0=vld1q_u32(ptr);               
                Q0=vaddq_u32(Q0,Q0);
                vst1q_u32(ptr,Q0);
                ptr+=4;

        }
        return;
}
Run Code Online (Sandbox Code Playgroud)

想知道阵列和向量之间的加载/存储操作是否消耗更多时间来抵消并行添加的好处.

更新:更多信息回应伊戈尔的回复.
1.代码发布在这里:
plain.c
plain.s
neon.c
neon.s
从两个汇编列表中的部分(标签)L7,我看到霓虹灯版本有更多的汇编指令.(因此更多时间采取?)2.
我在arm-gcc上使用-mfpu = neon编译,没有其他标志或优化.对于普通版本,根本没有编译器标志.
那是一个错字,SIZE的意思是大小;两者都是一样的.
4,5.由4000个元素组成.我在函数调用之前和之后使用gettimeofday()定时.NEON = 230us,普通= 155us.
是的,我在每种情况下印刷了元素.
除此之外,没有任何进步.

Igo*_*sky 3

这个问题相当模糊,你没有提供太多信息,但我会尽力给你一些指导。

  1. 在查看装配之前,您不会确切知道发生了什么。使用-S,卢克!
  2. 您没有指定编译器设置。您正在使用优化吗?循环展开?
  3. 第一个函数使用size,第二个函数使用SIZE,这是故意的吗?它们是一样的吗?
  4. 您尝试的数组的大小是多少?我不认为 N​​EON 对某些元素有任何帮助。
  5. 速度差异有多大?百分之几?几个数量级?
  6. 你检查过结果是一样的吗?您确定代码是等效的吗?
  7. 您使用相同的变量来获取中间结果。尝试将加法的结果存储在另一个变量中,这可能会有所帮助(尽管我希望编译器会很聪明并分配不同的寄存器)。另外,您可以尝试使用 shift ( vshl_n_u32) 而不是加法。

编辑:感谢您的回答。我环顾四周,发现了这个讨论,其中说(强调我的):

将数据从 NEON 转移到 ARM 寄存器是昂贵的,因此 Cortex-A8 中的 NEON 最适合用于几乎没有 ARM 管道交互的大型工作块。

在您的情况下,没有 NEON 到 ARM 的转换,只有加载和存储。尽管如此,并行操作的节省似乎被非 NEON 部件耗尽了。我希望在 NEON 中执行许多操作的代码能获得更好的结果,例如颜色转换。