是否有任何 memcpy() 实现使用多个处理器寄存器?
Does any memcpy() implementation use multiple processor registers?
memcpy()
据我所知通常实现为一个循环:
// Pseudo code - for illustration only
while(len--)
++*dst=++*src;
使用所有可用的 CPU 寄存器不是更有意义吗?!至少对于大副本?!
// Pseudo code - for illustration only
register srcA,dstA
register srcB,dstB
register srcC,dstC
while(len-=numreg)
{
*dstA=*srcA;
*dstB=*srcB;
*dstC=*srcC;
}
那么问题来了。 memcpy()
实现是否特别考虑可用的寄存器,还是留给编译器?!
Would it not make more sense to use all available CPU registers?! At
least for large copies?!
正确。
最快的实现是使用寄存器在汇编程序中编码:
void X_aligned_memcpy_sse2(void* dest, const void* src, const unsigned long size)
{
__asm
{
mov esi, src; //src pointer
mov edi, dest; //dest pointer
mov ebx, size; //ebx is our counter
shr ebx, 7; //divide by 128 (8 * 128bit registers)
loop_copy:
prefetchnta 128[ESI]; //SSE2 prefetch
prefetchnta 160[ESI];
prefetchnta 192[ESI];
prefetchnta 224[ESI];
movdqa xmm0, 0[ESI]; //move data from src to registers
movdqa xmm1, 16[ESI];
movdqa xmm2, 32[ESI];
movdqa xmm3, 48[ESI];
movdqa xmm4, 64[ESI];
movdqa xmm5, 80[ESI];
movdqa xmm6, 96[ESI];
movdqa xmm7, 112[ESI];
movntdq 0[EDI], xmm0; //move data from registers to dest
movntdq 16[EDI], xmm1;
movntdq 32[EDI], xmm2;
movntdq 48[EDI], xmm3;
movntdq 64[EDI], xmm4;
movntdq 80[EDI], xmm5;
movntdq 96[EDI], xmm6;
movntdq 112[EDI], xmm7;
add esi, 128;
add edi, 128;
dec ebx;
jnz loop_copy; //loop please
loop_copy_end:
}
}
来源:
Very fast memcpy for image processing?
首先你的伪代码是错误的,因为你忘了增加指针。当您考虑它时,您的优化就没有任何意义了。
另一个问题是您不能复制任意数量的字节,而这对于任何标准函数来说都是必须的。
您当然可以使用特定处理器功能为快速内存移动编写高度优化的函数,但它几乎无法替代标准 memcpy 函数
memcpy()
据我所知通常实现为一个循环:
// Pseudo code - for illustration only
while(len--)
++*dst=++*src;
使用所有可用的 CPU 寄存器不是更有意义吗?!至少对于大副本?!
// Pseudo code - for illustration only
register srcA,dstA
register srcB,dstB
register srcC,dstC
while(len-=numreg)
{
*dstA=*srcA;
*dstB=*srcB;
*dstC=*srcC;
}
那么问题来了。 memcpy()
实现是否特别考虑可用的寄存器,还是留给编译器?!
Would it not make more sense to use all available CPU registers?! At least for large copies?!
正确。
最快的实现是使用寄存器在汇编程序中编码:
void X_aligned_memcpy_sse2(void* dest, const void* src, const unsigned long size)
{
__asm
{
mov esi, src; //src pointer
mov edi, dest; //dest pointer
mov ebx, size; //ebx is our counter
shr ebx, 7; //divide by 128 (8 * 128bit registers)
loop_copy:
prefetchnta 128[ESI]; //SSE2 prefetch
prefetchnta 160[ESI];
prefetchnta 192[ESI];
prefetchnta 224[ESI];
movdqa xmm0, 0[ESI]; //move data from src to registers
movdqa xmm1, 16[ESI];
movdqa xmm2, 32[ESI];
movdqa xmm3, 48[ESI];
movdqa xmm4, 64[ESI];
movdqa xmm5, 80[ESI];
movdqa xmm6, 96[ESI];
movdqa xmm7, 112[ESI];
movntdq 0[EDI], xmm0; //move data from registers to dest
movntdq 16[EDI], xmm1;
movntdq 32[EDI], xmm2;
movntdq 48[EDI], xmm3;
movntdq 64[EDI], xmm4;
movntdq 80[EDI], xmm5;
movntdq 96[EDI], xmm6;
movntdq 112[EDI], xmm7;
add esi, 128;
add edi, 128;
dec ebx;
jnz loop_copy; //loop please
loop_copy_end:
}
}
来源: Very fast memcpy for image processing?
首先你的伪代码是错误的,因为你忘了增加指针。当您考虑它时,您的优化就没有任何意义了。
另一个问题是您不能复制任意数量的字节,而这对于任何标准函数来说都是必须的。
您当然可以使用特定处理器功能为快速内存移动编写高度优化的函数,但它几乎无法替代标准 memcpy 函数