我对手册页中的措辞感到困惑arch_prctl(2)
.具体来说,它指出:
64位段基的上下文切换相当昂贵. 通过在内核2.5或更高版本中使用modify_ldt(2)或使用set_thread_area(2)系统调用设置LDT,使用段选择器设置32位基址可能是更快的替代方法.只有当您想要设置大于4GB的基数时,才需要arch_prctl().可以使用带有MAP_32BIT标志的mmap(2)来分配前2GB地址空间中的内存.
这是否意味着使用此系统调用的进程的上下文切换将受到性能损失或具有哪些确切含义?
查看Linux内核的源代码后,似乎对于<4 GiB的地址使用LDT,而> 4 GiB地址使用特定于模型的寄存器.
来自do_arch_prctl
:
case ARCH_SET_FS: /* handle small bases via the GDT because that's faster to switch. */ if (addr <= 0xffffffff) { set_32bit_tls(task, FS_TLS, addr); if (doit) { load_TLS(&task->thread, cpu); loadsegment(fs, FS_TLS_SEL); } task->thread.fsindex = FS_TLS_SEL; task->thread.fs = 0; } else { task->thread.fsindex = 0; task->thread.fs = addr; if (doit) { /* set the selector to 0 to not confuse __switch_to */ loadsegment(fs, 0); ret = wrmsrl_safe(MSR_FS_BASE, addr); } } put_cpu(); break;
如何使用GDT比写入寄存器更快?此外,我假设更新FS和GS的价格仅在流程之间切换时支付,这意味着当没有其他流程计划运行时,通过系统调用进入内核没有额外成本?