arm/arm64 linux memcpy优化函数
在uncache区域memcpy时通常很慢,下面是一些优化:
arm下的memcpy实现:
void my_memcpy(volatile void char *dst, volatile unsigned void *src, int sz)
{
if (sz & 63) {
sz = (sz & -64) + 64;
}
asm volatile (
"NEONCopyPLD:
"
" VLDM %[src]!,{d0-d7}
"
" VSTM %[dst]!,{d0-d7}
"
" SUBS %[sz],%[sz],#0x40
"
" BGT NEONCopyPLD
"
: [dst]"+r"(dst), [src]"+r"(src), [sz]"+r"(sz) : : "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "cc", "memory");
}
arm64位下的优化:
uncached区域:
void my_memcpy(volatile void *dst, volatile void *src, int sz)
{
if (sz & 63) {
sz = (sz & -64) + 64;
}
asm volatile (
"NEONCopyPLD:
"
"sub %[dst], %[dst], #64
"
"1:
"
"ldnp q0, q1, [%[src]]
"
"ldnp q2, q3, [%[src], #32]
"
"add %[dst], %[dst], #64
"
"subs %[sz], %[sz], #64
"
"add %[src], %[src], #64
"
"stnp q0, q1, [%[dst]]
"
"stnp q2, q3, [%[dst], #32]
"
"b.gt 1b
"
: [dst]"+r"(dst), [src]"+r"(src), [sz]"+r"(sz) : : "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "cc", "memory");
}
cached区域:
void my_memcpy(volatile void *dst, volatile void *src, int sz)
{
if (sz & 63) {
sz = (sz & -64) + 64;
}
asm volatile (
"NEONCopyPLD:
"
"sub %[src], %[src], #32
"
"sub %[dst], %[dst], #32
"
"1:
"
"ldp q0, q1, [%[src], #32]
"
"ldp q2, q3, [%[src], #64]!
"
"subs %[sz], %[sz], #64
"
"stp q0, q1, [%[dst], #32]
"
"stp q2, q3, [%[dst], #64]!
"
"b.gt 1b
"
: [dst]"+r"(dst), [src]"+r"(src), [sz]"+r"(sz) : : "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "cc", "memory");
}
