微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 在Cortex-A8平台下memcpy ARM/NEON汇编性能的测试

在Cortex-A8平台下memcpy ARM/NEON汇编性能的测试

时间:11-10 来源:互联网 点击:
    • 一定会使用pld指令提示ARM预先把cache line填充好。
    • pld指令中的offset很有讲究。一般为64-byte的倍数。在ARMv5TE平台是一个循环用一个pld指令。在Cortex-A8平台上速度更快,需要一个循环用2~3个pld指令填充cache line。这样一个循环消费2~3个时钟周期换得cache hit rate提高,效果是值得的。
    • 进一步的,Cortex-A8架构提供了preload engine指令,可以让软件更深地影响cache,以便让cache hit rate得到提高。不过要在用户空间使用ple指令,需要在OS中打补丁开放权限。
  1. C语言版本

    C语言版本主要是做对比。采用两个实现:

  2. 32-bit wide copy。后面标记为in32_cpy。
  3. 16-byte wide copy。后面标记为vec_cpy。这个实现的技巧是采用gcc的向量扩展"__attribute__ ((vector_size(16)))",在C语言层级实现16-byte wide copy,将具体实现交给编译器。

    值得注意的事情是,编译器不会主动插入pld指令。因为编译器无法判断应用对内存的访问模式。

  4. ARM汇编版本

    ARM汇编版本也主要是做对比。采用两个实现:

  5. Siarhei Siamashka实现[15]。后面标记为arm9_memcpy。他是为Nokia N770做的优化。
  6. Nicolas Pitre实现[16]。后面标记为armv5te_memcpy。这是目前glibc里面缺省的arm memcpy实现。
  7. NEON汇编版本

    NEON汇编版本采用四个实现:

  8. M?ns Rullg?rd实现[19]。这是一个128-byte-align block的最简单的实现。没有判断不是128-byte align的情况。因此不是实用的版本。但通过这类实现,可以考察memcpy性能的极限。他总共提供4种实现。
  9. 全ARM汇编的实现。后面标记为memcpy_arm。此外,笔者还将其中的pld指令去掉,做为对比试验,考察pld指令的影响。后面标记为memcpy_arm_nopld。
  10. 全NEON汇编的实现。后面标记为memcpy_neon。此外,笔者还将其中的pld指令去掉,做为对比试验,考察pld指令的影响。后面标记为memcpy_neon_nopld。
  11. ARM / NEON指令交替使用的实现。后面标记为memcpy_armneon。此外,笔者还将其中的pld指令去掉,做为对比试验,考察pld指令的影响。后面标记为memcpy_armneon_nopld。
  12. ple + NEON的实现。后面标记为memcpy_ple_neon。此外,笔者还将其中的NEON指令换成ARM指令,做为对比试验,考察ple指令对ARM/NEON指令的影响。后面标记为memcpy_ple_arm。因为这个实现需要对linux kernel打补丁,在omap3430平台上没有成功。在Snapdragon平台上更换kernel有些麻烦,所以也没有测试。
  13. CodeSourcery实现[17]。这是CodeSourcery toolchain中的glibc里面的实现。也分两种实现。
  14. ARM实现。后面标记为memcpy_arm_codesourcery。笔者还将其中的pld指令去掉,做为对比试验,考察pld指令的影响。后面标记为memcpy_arm_codesourcery_nopld。
  15. NEON实现。后面标记为memcpy_neon_codesourcery。这也是Android bionic里面采用的NEON实现。笔者还将其中的pld指令去掉,做为对比试验,考察pld指令的影响。后面标记为memcpy_neon_codesourcery_nopld。
  16. QualComm实现[18]。后面标记为memcpy_neon_qualcomm。这是QualComm在Code Aurora Forum中为Snapdragon平台开发的优化版本。主要是对8660/8650A平台的优化。这个版本的特点是针对L2 cache line size=128bytes而设计,pld offset设置得特别大。结果在其它Cortex-A8平台上没有效果。所以笔者将pld offset改为M?ns Rullg?rd实现的数值。笔者还将其中的pld指令去掉,做为对比试验,考察pld指令的影响。后面标记为memcpy_neon_qualcomm_nopld。
  17. Siarhei Siamashka实现[20]。后面标记为memcpy_neon_siarhei。这是Siarhei Siamashka向glibc提交的NEON版本,没有被glibc采纳。但是在MAEMO项目中得到采用。这个版本的特点是pld offset是从小到大增长的,以期望适应block size的变化。
  18. 测试方案介绍

    测试方案十分简单。参考了movial memory tester的实现[21]。执行步骤如下:

  19. 先对每个实现进行正确性的验证。主要方法是以随机的block size & offset,填充随机的内容,然后执行memcpy操作,然后再用系统的memcmp函数对两块内存做校验。
  20. 然后对每个实现以不同的block size调用400次。如果total copy size < 1MB,则增加count直到满足要求。对总操作计时。
  21. 以total copy size / total copy time公式计算memcpy bandwidth。

    上述提到的block size = 2^n ( 7 <= n <= 23 )。

    此外,这个测试程序运行在openembedded-gpe软件系统中。QualComm / Samsung硬件平台只提供Android软件系统,要更换到GPE系统有些麻烦,则采用chroot方式进行测试。不论是哪种软件平台,都是进入到图形系统后,静置,等待黑屏,然后再进行测试。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top