本文介绍了基于ARMv7架构的Cortex-A8芯片(FreeScale i.MX51 / i.MX53/QualComm msm8x50 / msm7x30/Samsung s5pc100 / s5pc110/TI omap 3430 / omap 3730芯片)上采用C语言、ARM汇编和NEON汇编实现的memcpy的性能对比,并输入分析了NEON指令(不同处理器的NEON内存位宽从64-bit到128-bit不等)和cache的预取preload(preload engine指令)对性能的影响。最终结论表明1.在拷贝块大小block size = 512B ~ 32K之间,有一个性能高台,block size = 256K也有一个性能的转折。这个特性体现了芯片32KB L1 / 256KB L2 cache的影响;2. NEON指令的性能总是要高于ARM指令的性能。随着发展ARM/NEON指令之间性能差在缩小。交替使用ARM/NEON指令,性能往往要差于NEON版本;3. 如果没有很好的模型设计,软件去干预cache的使用,很容易会造成性能的恶化; 4. 在fit in cache条件下,Snapdragon平台有最好的性能; 5. 在out of cache条件下,s5pc110有最好的性能; 6. 在同一个硬件平台下,超频对memory性能影响很小; 7. 同一种的实现,在不同的硬件平台上都有不同的表现。没有一种实现在所有平台上是最好的。
在C run time library中,memcpy是重要的函数,对应用软件的性能有着重要的影响。ARM芯片发展到Cortex-A8[1][2]架构,不但频率有了很大提升,而且架构设计有了很大地改进。其中增加的NEON指令,是类似于原先X86平台下的MMX指令,是为多媒体而设计。但因为这类指令一次可以处理64-bit数据,对memcpy函数性能提升也很有帮助。本文主要是测试采用NEON[2]指令的多种memcpy实现,探讨NEON指令和预取(preload)指令对性能的影响,以及在芯片优化和工艺进步后,这些影响的变化趋势。同时希望芯片设计人员在了解软件实现的基础上,给予一个知其然,也知其所以然的解释,进而指导进一步提高性能的方向。
本次的测试平台来源于笔者工作项目中接触到的Cortex-A8平台。见下面列表:
i.MX5 family的介绍见[6][7]。其中i.MX535可以运行在800MHZ / 1000MHZ两种频率上。
Snapdragon的介绍见[8][9][10]。其中msm7x30可以运行在800MHZ / 1000MHZ两种频率上。此外Snapdragon cache特别之处是128-bit wide(NEON), 128-byte / line。标准Cortex-A8中,该数值为64-bit wide(NEON), 64-byte / line。这对性能有较大影响。
s5pc family参考平台见[11]。
omap3 family参考平台见[12][13][14]。
memcpy的实现在ARM平台上的发展有3类版本:
ARM公司的文档[4]对memcpy的实现有很好描述。有人[5][19][20]还进一步阐述了实现原理和技巧。简述如下:
C语言版本主要是做对比。采用两个实现:
值得注意的事情是,编译器不会主动插入pld指令。因为编译器无法判断应用对内存的访问模式。
ARM汇编版本也主要是做对比。采用两个实现:
NEON汇编版本采用四个实现:
测试方案十分简单。参考了movial memory tester的实现[21]。执行步骤如下:
上述提到的block size = 2^n ( 7 <= n <= 23 )。
此外,这个测试程序运行在openembedded-gpe软件系统中。QualComm / Samsung硬件平台只提供Android软件系统,要更换到GPE系统有些麻烦,则采用chroot方式进行测试。不论是哪种软件平台,都是进入到图形系统后,静置,等待黑屏,然后再进行测试。
下表是运行环境的统计。
硬件平台 |
软件环境 |
imx51 800MHZ |
openembedded-gpe |
imx53 1000MHZ |
openembedded-gpe |
imx53 800MHZ |
openembedded-gpe |
msm7230 1000MHZ |
Android + chroot |
msm7230 800MHZ |
Android + chroot |
msm8250 1000MHZ |
Android + chroot |
omap3430 550MHZ |
openembedded-gpe |
omap3730 1000MHZ |
openembedded-gpe |
s5pc100 665MHZ |
Android + chroot |
s5pc110 1000MHZ |
Android + chroot |
下表是测试项目的统计。
实现方案 |
i.MX51 |
i.MX53 |
Snapdragon |
s5pc1xx |
omap3430 |
omap3730 |
int32_cpy |
YES |
YES |
YES |
YES |
YES |
YES |
vec_cpy |
YES |
YES |
YES |
YES |
YES |
YES |
arm9_memcpy |
YES |
YES |
YES |
YES |
YES |
YES |
armv5te_memcpy |
YES |
YES |
YES |
YES |
YES |
YES |
memcpy_arm |
YES |
YES |
YES |
YES |
YES |
YES |
memcpy_arm_nopld |
YES |
NO |
YES |
YES |
YES |
YES |
memcpy_neon |
YES |
YES |
YES |
YES |
YES |
YES |
memcpy_neon_nopld |
YES |
NO |
YES |
YES |
YES |
YES |
memcpy_armneon |
YES |
YES |
YES |
YES |
YES |
YES |
memcpy_ple_arm |
YES |
YES |
N/A |
YES |
N/A |
YES |
memcpy_ple_neon |
YES |
YES |
N/A |
YES |
N/A |
YES |
memcpy_arm_codesourcery |
YES |
YES |
YES |
YES |
YES |
YES |
memcpy_arm_codesourcery_nopld |
YES |
NO |
YES |
YES |
YES |
YES |
memcpy_neon_codesourcery |
YES |
YES |
YES |
YES |
YES |
YES |
memcpy_neon_codesourcery_nopld |
YES |
NO |
YES |
YES |
YES |
YES |
memcpy_neon_qualcomm |
YES |
YES |
YES |
YES |
YES |
YES |
memcpy_neon_qualcomm_nopld |
YES |
NO |
YES |
YES |
YES |
YES |
memcpy_neon_siarhei |
YES |
YES |
YES |
YES |
YES |
YES |
注1:因为i.MX53 EVK板子发生故障,未能测试所有no pld的测试项。
注2:在给omap3430打开preload engine后,测试产生非法指令错,未能测试ple的测试项。
注3:要替换Snapdragon kernel有些麻烦, 未能测试ple的测试项。
下面的图表限于页面大小不能很好地显示细节。具体的数据和大图可到数据表文档中查看。
性能因为block size分为fit in cache / out of cache两种表现,所以做两个剖面做对比分析。
因为M?ns Rullg?rd的实现最简单,除了一个循环体外,没有其它判断代码,可以认为是体现平台速度极限的实现。
通过同一种实现在不同硬件平台上性能的对比,结合上一节的图表,可以评价一种实现的平均性能,也就是适应性。
因为在Cortex-A8系列芯片里,NEON模块是必有的。而在Cortex-A9系列芯片里,NEON模块是可选的。因为NEON模块会影响到die size,因而影响功耗和成本。因此有些Cortex-A9芯片,如Nvidia Tegra250,没带有NEON模块。那么有无NEON模块会对软件性能造成什么样的影响呢?
http://en.wikipedia.org/wiki/ARM_Cortex-A8
http://infocenter.arm.com/help/topic/com.arm.doc.ddi0344k/index.html
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0344f/Chdebced.html
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka13544.html
http://hardwarebug.org/2008/12/31/arm-neon-memory-hazards/
http://en.wikipedia.org/wiki/I.MX
http://www.7-cpu.com/cpu/imx515.html
http://en.wikipedia.org/wiki/Snapdragon_(System_on_Chip)
http://www.bdti.com/InsideDSP/2007/11/14/Qualcomm
http://www.7-cpu.com/cpu/Snapdragon.html
http://hardkernel.com/
http://en.wikipedia.org/wiki/OMAP3
http://omapworld.com/
http://beagleboard.org/
http://lists.maemo.org/pipermail//maemo-developers/2006-March/003269.html
http://sourceware.org/ml/libc-ports/2006-10/msg00024.html
http://www.codesourcery.com/
https://www.codeaurora.org/patches/quic/qsd/SAMPLE_3918_NEON_MEMOPS_20101001.tar.gz
http://groups.google.com/group/beagleboard/browse_thread/thread/12c7bd415fbc0993/c54dde7b9d55cf99
http://sourceware.org/ml/libc-ports/2009-07/msg00003.html
http://sandbox.movial.com/gitweb?p=mmem.git;a=summary
http://houh-1984.blog.163.com
转载自Shuyong Chen http://tektalk.org/wp-content/uploads/2011/03/memspeed.odt
本文介绍了基于ARMv7架构的Cortex-A8芯片(FreeScale i.MX51 / i.MX53/QualComm msm8x50 / msm7x30/Samsung s5pc100 / s5pc110/TI omap 3430 / omap 3730芯片)上采用C语言、ARM汇编和NEON汇编实现的memcpy的性能对比,并输入分析了NEON指令(不同处理器的NEON内存位宽从64-bit到128-bit不等)和cache的预取preload(preload engine指令)对性能的影响。最终结论表明1.在拷贝块大小block size = 512B ~ 32K之间,有一个性能高台,block size = 256K也有一个性能的转折。这个特性体现了芯片32KB L1 / 256KB L2 cache的影响;2. NEON指令的性能总是要高于ARM指令的性能。随着发展ARM/NEON指令之间性能差在缩小。交替使用ARM/NEON指令,性能往往要差于NEON版本;3. 如果没有很好的模型设计,软件去干预cache的使用,很容易会造成性能的恶化; 4. 在fit in cache条件下,Snapdragon平台有最好的性能; 5. 在out of cache条件下,s5pc110有最好的性能; 6. 在同一个硬件平台下,超频对memory性能影响很小; 7. 同一种的实现,在不同的硬件平台上都有不同的表现。没有一种实现在所有平台上是最好的。