【发布时间】:2019-12-30 04:34:50
【问题描述】:
在了解我的应用程序的分析结果(I/O-heavy)时,我面临copy_user_enhanced_fast_string 是最热门的区域之一。在用户空间和内核空间之间复制时调用它。 x86 上的The implementation 看起来像:
ENTRY(copy_user_enhanced_fast_string)
ASM_STAC
cmpl $64,%edx
jb .L_copy_short_string /* less then 64 bytes, avoid the costly 'rep' */
movl %edx,%ecx
1: rep
movsb
xorl %eax,%eax
ASM_CLAC
ret
.section .fixup,"ax"
12: movl %ecx,%edx /* ecx is zerorest also */
jmp .Lcopy_user_handle_tail
.previous
_ASM_EXTABLE_UA(1b, 12b)
ENDPROC(copy_user_enhanced_fast_string)
为什么不使用vmovaps/vmovups?难道没有证明 AVX 在复制可用的地方没有性能优势吗?
【问题讨论】:
-
"一些 CPU 正在添加增强型 REP MOVSB/STOSB 指令。如果启用,建议使用增强型 REP MOVSB/STOSB。"
-
也许有一种方法可以使用 mmap'ed IO 并避免完全复制。
-
@TrentP 将文件
mmap然后memcpy(使用AVX)到某个正确的位置可能是个好主意。你是这个意思吗? -
就像@Peter Cordes 所说,使用
mmap的最佳方法是不复制数据,而是直接从映射位置使用它。 mmap+copy 不会比 read 好多少。但是,您的问题并未说明您正在访问文件,并且还有很多其他方法可以从内核获取数据。具有高吞吐量的接口,例如使用 V4L 进行视频捕获,通常具有避免复制的 mmap'ed 模式。另请参阅sendfile()和splice(),了解使用管道和套接字时避免复制的方法。 -
使用 mmap+copy,您需要额外的页表操作来将文件映射到进程的地址空间,但可以节省每次 read() 的系统调用模式切换开销。任何可能副本本身都更快。总体上可能更快或更慢。如果您不能复制数据,就会获得收益。
标签: linux assembly linux-kernel x86-64