用neon intrinsics替换memcpy

时间:2015-05-07 16:58:24

标签: arm simd neon cortex-a

我正试图击败" memcpy"通过编写霓虹内在函数来实现相同的功能。以下是我的逻辑:

uint8_t* m_input;  //Size as 400 x300
uint8_t* m_output; //Size as 400 x300
//not mentioning the complete code base for memory creat 

memcpy(m_output, m_input, sizeof(m_output[0]) * 300* 400);

氖:

int32_t ht_index,wd_index;
uint8x16_t vector8x16_image;

for(int32_t htI =0;htI < m_roiHeight;htI++){
    ht_index = htI * m_roiWidth ;

    for(int32_t wdI = 0;wdI < m_roiWidth;wdI+=16){
        wd_index = ht_index + wdI;
        vector8x16_image = vld1q_u8(m_input);

        vst1q_u8(&m_output[wd_index],vector8x16_image);
    }
}

我在imx6硬件上多次验证了这些结果。

结果:

Memcpy :0.039 milisec
neon memcpy: 0.02841 milisec

我读了一些没有预告说明的东西,我们不能忘记成为会员。

如果是,那么我的代码如何给出这些结果。 是对还是

1 个答案:

答案 0 :(得分:6)

如果写入正确,非NEON memcpy()应该能够使设备上的L3带宽饱和,但对于较小的传输(完全适合L1或L2缓存),事情可能会有所不同。您的测试可能适合L2缓存。

不幸的是memcpy必须适用于任何大小的调用,因此它无法合理优化缓存中和缓存外的情况,同时优化非常短的副本,其中包含成本检测哪种优化最好成为主导因素。

即便如此,您的测试也可能不公平。您必须确保两个实现都不受不同的缓存前提条件或不同的虚拟页面布局的影响。

确保两个测试都没有完全在另一个之前运行。测试一个实现中的一些,然后测试一些其他实现,然后回到第一个,然后回到第二个,以确保它们不受任何预热条件的影响。并对两者使用相同的缓冲区,以确保虚拟地址空间的不同部分没有特征,只会损害一个实现。

此外,有些情况下memcpy无法处理,但这些对于大额转移来说并不重要。