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"); }