有没有一个`x86`指令可以告诉我们指令正在运行在哪个核心上?
有没有一个`x86`指令可以告诉我们指令运行在哪个核心上?
除了已经描述的CPUID和RDTSCP指令之外,还有一个新的RDPID指令(Intel SDM下载页面)专门用于这个目的。
描述
将IA32_TSC_AUX MSR(地址C0000103H)的值读入目标寄存器。CS.D的值和操作数大小前缀(66H和REX.W)不会影响RDPID指令的行为。
注意:
RDPID将处理器核心ID作为uint32_r或uint64_r读取,因此读取的值不在顺序范围[0,MAX_CPU_COUNT]内。
RDPID是一条新指令,因此在硬件上的支持并不广泛。
有哪些CPU支持它,以及可以检查其支持的标志是什么?
,对于rdpid的cpuid是有的:software.intel.com/sites/default/files/managed/c5/15/… eax=07H - ecx位22“位22:RDPID。如果为1,则支持读取处理器ID。”
根据以上内容可以得出,RDPID是一条新的x86指令,用于读取处理器核心ID。它通过读取IA32_TSC_AUX MSR的值来实现,该指令的行为不受CS.D和操作数大小前缀的影响。然而,需要注意的是,RDPID指令并不被所有硬件广泛支持。为了确定一个CPU是否支持RDPID指令,可以使用CPUID指令并检查eax=07H的ecx位22。如果ecx位22为1,则表示该CPU支持读取处理器ID。
这篇文章介绍了RDPID指令的存在、用途和支持情况。对于需要确定指令运行在哪个核心上的开发者来说,RDPID指令提供了一种简便的方式来获取处理器核心ID。然而,由于其不被所有硬件广泛支持,开发者在使用RDPID指令之前需要先判断CPU是否支持。
最近的一些x86 / x86_64 CPU中有“RDTSCP”指令的变体,可以用来读取时间戳计数器和处理器ID。在Linux中,操作系统会将核心ID写入IA32_TSC_AUX,并且可以通过RDTSCP指令来访问这个值。此外,Linux还提供了vsyscall getcpu函数来通过RDTSCP指令或GDT(GDT_ENTRY_PER_CPU)来访问CPU ID。这个函数的目的是为了允许程序针对每个CPU的数据进行优化或进行NUMA优化。此外,还有一种名为RDPID的指令可以读取IA32_TSC_AUX寄存器的值。从2018年的"Ice Lake"微架构开始,这个指令将会被启用。
参考资料:
- http://ref.x86asm.net/coder32-abc.html#R
- http://lxr.free-electrons.com/source/arch/x86/kernel/vsyscall_64.c?v=3.13#L330
- http://lxr.free-electrons.com/source/arch/x86/kernel/vsyscall_64.c?v=3.13#L341
- http://man7.org/linux/man-pages/man2/getcpu.2.html
- http://www.intel.com/content/dam/www/public/us/en/documents/white-papers/ia-32-ia-64-benchmark-code-execution-paper.pdf#page=15
- http://www.felixcloutier.com/x86/RDTSCP.html
- https://github.com/zneak/x86doc
- https://hjlebbink.github.io/x86doc/html/RDPID.html
- https://software.intel.com/sites/default/files/managed/c5/15/architecture-instruction-set-extensions-programming-reference.pdf