我正在使用基于ARM的Xilinx Zynq 7000 SoC。我在处理DMA缓冲区(需要帮助在Xilinx / ARM SoC(Zynq 7000)上映射预留的**可缓存** DMA缓冲区)方面遇到了困难,因此我追求更快的memcpy。
我一直在研究使用Neon指令和内联汇编编写更快的ARM memcpy。无论glibc有什么,它都很糟糕,特别是如果我们从未缓存的DMA缓冲区复制。
我从各种来源组合了自己的复制函数,包括:
我所做的主要是省略了预取指令,因为我认为它在非缓存内存上是无用的。
这样做使速度比glibc memcpy快了4.7倍。速度从大约70MB /秒提高到大约330MB /秒。
不幸的是,这远远不及来自缓存内存的memcpy快,后者运行速度大约为系统memcpy的720MB /秒和NEON版本的620MB /秒(可能比较慢,因为我的memcpy没有进行预取,也许)。
有谁可以帮助我想出什么办法来弥补这个性能差距吗?
我尝试了很多事情,例如一次复制更多,两次负载后跟两次存储。我可以尝试使用预取来证明它是无用的。还有其他的想法吗?
我一直在研究使用Neon指令和内联汇编编写更快的ARM memcpy。无论glibc有什么,它都很糟糕,特别是如果我们从未缓存的DMA缓冲区复制。
我从各种来源组合了自己的复制函数,包括:
- Fast ARM NEON memcpy
- gcc中的arm内联汇编
- http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka13544.html
对我来说,主要的区别在于我试图从一个未缓存的缓冲区中进行复制,因为它是一个DMA缓冲区,而ARM对于缓存的DMA缓冲区的支持是不存在的。
所以这就是我写的内容:
void my_copy(volatile unsigned char *dst, volatile unsigned char *src, int sz)
{
if (sz & 63) {
sz = (sz & -64) + 64;
}
asm volatile (
"NEONCopyPLD: \n"
" VLDM %[src]!,{d0-d7} \n"
" VSTM %[dst]!,{d0-d7} \n"
" SUBS %[sz],%[sz],#0x40 \n"
" BGT NEONCopyPLD \n"
: [dst]"+r"(dst), [src]"+r"(src), [sz]"+r"(sz) : : "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "cc", "memory");
}
我所做的主要是省略了预取指令,因为我认为它在非缓存内存上是无用的。
这样做使速度比glibc memcpy快了4.7倍。速度从大约70MB /秒提高到大约330MB /秒。
不幸的是,这远远不及来自缓存内存的memcpy快,后者运行速度大约为系统memcpy的720MB /秒和NEON版本的620MB /秒(可能比较慢,因为我的memcpy没有进行预取,也许)。
有谁可以帮助我想出什么办法来弥补这个性能差距吗?
我尝试了很多事情,例如一次复制更多,两次负载后跟两次存储。我可以尝试使用预取来证明它是无用的。还有其他的想法吗?