在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中打补丁开放权限。
C语言版本
C语言版本主要是做对比。采用两个实现:
- 32-bit wide copy。后面标记为in32_cpy。
16-byte wide copy。后面标记为vec_cpy。这个实现的技巧是采用gcc的向量扩展"__attribute__ ((vector_size(16)))",在C语言层级实现16-byte wide copy,将具体实现交给编译器。
值得注意的事情是,编译器不会主动插入pld指令。因为编译器无法判断应用对内存的访问模式。
ARM汇编版本
ARM汇编版本也主要是做对比。采用两个实现:
- Siarhei Siamashka实现[15]。后面标记为arm9_memcpy。他是为Nokia N770做的优化。
- Nicolas Pitre实现[16]。后面标记为armv5te_memcpy。这是目前glibc里面缺省的arm memcpy实现。
NEON汇编版本
NEON汇编版本采用四个实现:
- M?ns Rullg?rd实现[19]。这是一个128-byte-align block的最简单的实现。没有判断不是128-byte align的情况。因此不是实用的版本。但通过这类实现,可以考察memcpy性能的极限。他总共提供4种实现。
- 全ARM汇编的实现。后面标记为memcpy_arm。此外,笔者还将其中的pld指令去掉,做为对比试验,考察pld指令的影响。后面标记为memcpy_arm_nopld。
- 全NEON汇编的实现。后面标记为memcpy_neon。此外,笔者还将其中的pld指令去掉,做为对比试验,考察pld指令的影响。后面标记为memcpy_neon_nopld。
- ARM / NEON指令交替使用的实现。后面标记为memcpy_armneon。此外,笔者还将其中的pld指令去掉,做为对比试验,考察pld指令的影响。后面标记为memcpy_armneon_nopld。
- ple + NEON的实现。后面标记为memcpy_ple_neon。此外,笔者还将其中的NEON指令换成ARM指令,做为对比试验,考察ple指令对ARM/NEON指令的影响。后面标记为memcpy_ple_arm。因为这个实现需要对linux kernel打补丁,在omap3430平台上没有成功。在Snapdragon平台上更换kernel有些麻烦,所以也没有测试。
- CodeSourcery实现[17]。这是CodeSourcery toolchain中的glibc里面的实现。也分两种实现。
- ARM实现。后面标记为memcpy_arm_codesourcery。笔者还将其中的pld指令去掉,做为对比试验,考察pld指令的影响。后面标记为memcpy_arm_codesourcery_nopld。
- NEON实现。后面标记为memcpy_neon_codesourcery。这也是Android bionic里面采用的NEON实现。笔者还将其中的pld指令去掉,做为对比试验,考察pld指令的影响。后面标记为memcpy_neon_codesourcery_nopld。
- 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。
- Siarhei Siamashka实现[20]。后面标记为memcpy_neon_siarhei。这是Siarhei Siamashka向glibc提交的NEON版本,没有被glibc采纳。但是在MAEMO项目中得到采用。这个版本的特点是pld offset是从小到大增长的,以期望适应block size的变化。
测试方案介绍
测试方案十分简单。参考了movial memory tester的实现[21]。执行步骤如下:
- 先对每个实现进行正确性的验证。主要方法是以随机的block size & offset,填充随机的内容,然后执行memcpy操作,然后再用系统的memcmp函数对两块内存做校验。
- 然后对每个实现以不同的block size调用400次。如果total copy size < 1MB,则增加count直到满足要求。对总操作计时。
以total copy size / total copy time公式计算memcpy bandwidth。
上述提到的block size = 2^n ( 7 <= n <= 23 )。
此外,这个测试程序运行在openembedded-gpe软件系统中。QualComm / Samsung硬件平台只提供Android软件系统,要更换到GPE系统有些麻烦,则采用chroot方式进行测试。不论是哪种软件平台,都是进入到图形系统后,静置,等待黑屏,然后再进行测试。
下
Cortex-A8平台memcpyARMNEON汇编性 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)