是否有一个`x86`指令来告诉正在运行指令的核心?

时间:2014-03-10 19:57:29

标签: assembly x86 x86-64

当我cat /proc/cpuinfo时,我会看到8个核心,ID为07

是否有x86指令报告指令本身正在运行的核心的核心ID?

我查看了cpuid,但在任何参数设置下似乎都没有返回coreid

5 个答案:

答案 0 :(得分:10)

答案 1 :(得分:9)

英特尔®64和IA-32架构软件开发人员手册第3A卷:系统编程指南,第1部分 8.4.5识别MP系统中的逻辑处理器列表,其中包括:

  

此APIC ID由CPUID.0BH:EDX [31:0]

报告

请注意,这并不等于linux内核的编号。在内核中有一个x86_cpu_to_apicid表,您可以阅读。当然内核也知道代码执行的cpu,而不必咨询APIC:

 * smp_processor_id(): get the current CPU ID.
 *
 * if DEBUG_PREEMPT is enabled then we check whether it is
 * used in a preemption-safe way. (smp_processor_id() is safe
 * if it's used in a preemption-off critical section, or in
 * a thread that is bound to the current CPU.)

答案 2 :(得分:4)

除了已经描述的CPUID和RDTSCP指令之外,还有一个新的RDPID指令(Intel SDM download page)完全用于此目的。

  

描述

     

将IA32_TSC_AUX MSR(地址C0000103H)的值读入目标寄存器。 CS.D的价值   和操作数大小前缀(66H和REX.W)不会影响RDPID指令的行为。

备注:

RDPID将处理器核心ID读取为uint32_r或uint64_r,因此读取值不会在顺序范围内[0,MAX_CPU_COUNT]

RDPID是新指令,因此硬件不广泛支持

答案 3 :(得分:2)

你会看到8个“虚拟CPU”,而不是内核,所以如果你有一个4核 Ivy Bridge CPU,每个核心有2个硬件线程,你可以看到哪些vCPU共享通过/sys/devices/system/cpu/cpu[0-7]/topology/thread_siblings_list中的条目核心。

另一个答案提出了使用cpuid的好建议,但我不认为您可以确定cpuid指令在与感兴趣的指令相同的vCPU上执行,除非你将线程固定到vCPU(在这种情况下它是相当多余的),因为你无法知道内核在感兴趣的指令之间没有将你的线程从一个vCPU迁移到另一个vCPU执行了cpuid指令执行的时间。

简而言之,绝大多数情况下,两个“关闭”指令将在同一个vCPU上执行,但是如果没有固定则无法保证,如果你已经固定了线程,那么你已经知道它正在运行什么vCPU ,所以这有点无意义。

答案 4 :(得分:0)

taskset + __rdtscp可运行示例

最后,对于那些想与x86内在函数+ taskset一起玩的人:

rdtscp.c

#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

#include <x86intrin.h>

int main(void) {
    uint32_t pid;
    printf("0x%016" PRIX64 "\n", (uint64_t)__rdtscp(&pid));
    printf("0x%08" PRIX32 "\n", pid);
    return EXIT_SUCCESS;
}

GitHub upstream

然后编译并运行,同时控制它在with taskset上运行哪个内核:

gcc -ggdb3 -O0 -std=c99 -Wall -Wextra -pedantic -o rdtscp.out rdtscp.c
./taskset -c 0 ./rdtscp.out
./taskset -c 1 ./rdtscp.out

然后对于每次运行,第二行显示CPU ID,与任务集设置的值匹配。

在具有Intel Core i7-7820HQ的Ubuntu 19.04 amd64中进行了测试。