linux cpu数物理核逻辑核的查看方法及线程进程的绑定方法

本文介绍了CPU核心、物理核与逻辑核的概念及其查看方法,并提供了进程与线程绑定到特定CPU核心的技术实现细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

cpu数,物理核,逻辑核的关系:

逻辑CPU个数 > 物理CPU个数 * CPU内核数 开启了超线程
逻辑CPU个数 = 物理CPU个数 * CPU内核数 没有开启超线程

cpu数,物理核,逻辑核的查看方法:

#cat /proc/cpuinfo

processor  : 0
vendor_id  :GenuineIntel
cpu family  :6
model    :26
model name :Intel(R) Xeon(R) CPU           E5520  @ 2.27GHz
stepping    :5
cpu MHz    :1600.000
cache size  : 8192 KB
physical id  :0
siblings    :8
core id     : 0
cpu cores   :4
apicid         :0
fpu       :yes
fpu_exception :yes
cpuid level   : 11
wp      :yes
flags      : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm syscall nx rdtscp lm constant_tsc ida nonstop_tsc pni monitor ds_cpl vmx est tm2 cx16 xtpr popcnt lahf_lm
bogomips   :4522.12
clflush size  :64
cache_alignment  : 64
address sizes    : 40 bits physical, 48 bits virtual
power management :
以上输出项的含义如下:
processor :系统中逻辑处理核的编号。对于单核处理器,则课认为是其CPU编号,对于多核处理器则可以是物理核、或者使用超线程技术虚拟的逻辑核
vendor_id :CPU制造商      
cpu family :CPU产品系列代号
model   :CPU属于其系列中的哪一代的代号
model name:CPU属于的名字及其编号、标称主频
stepping   :CPU属于制作更新版本
cpu MHz   :CPU的实际使用主频
cache size   :CPU二级缓存大小
physical id   :单个CPU的标号
siblings       :单个CPU逻辑物理核数
core id        :当前物理核在其所处CPU中的编号,这个编号不一定连续
cpu cores    :该逻辑核所处CPU的物理核数
apicid          :用来区分不同逻辑核的编号,系统中每个逻辑核的此编号必然不同,此编号不一定连续
fpu             :是否具有浮点运算单元(Floating Point Unit)
fpu_exception  :是否支持浮点计算异常
cpuid level   :执行cpuid指令前,eax寄存器中的值,根据不同的值cpuid指令会返回不同的内容
wp             :表明当前CPU是否在内核态支持对用户空间的写保护(Write Protection)
flags          :当前CPU支持的功能
bogomips   :在系统内核启动时粗略测算的CPU速度(Million Instructions Per Second)
clflush size  :每次刷新缓存的大小单位
cache_alignment :缓存地址对齐单位
address sizes     :可访问地址空间位数
power management :对能源管理的支持,有以下几个可选支持功能:
  ts:  temperature sensor
  fid:   frequency id control
  vid:  voltage id control
  ttp:  thermal trip
  tm:
  stc:
  100mhzsteps:
  hwpstate:

processor:逻辑核的个数(逻辑核的id)
physical id:物理CPU的id
cpu cores:每个物理CPU的物理核个数
siblings:每个物理CPU上逻辑CPU个数
core id:每个CPU上的物理核的id

查看CPU(各个逻辑核)占用情况:

# top
remark:在top命令下,点击"1"可以查看各个逻辑核的占用情况

进程绑定逻辑核:


#include <stdio.h>  
//g++ -o test test.cpp
/*
启动两个实例,将进程都绑定到Cpu0:
taskset -c 0 ./test
taskset -c 0 ./test
通过top, 输入“1”查看系统cpu状况:
Cpu1空闲,Cpu0使用100%
继续测试,将pid为18057的test迁移到CPU1上运行,执行:
$ taskset -pc  1 18057
pid 18057's current affinity list: 0
pid 18057's new affinity list: 1
Cpu0及Cpu1都进入忙碌状态了!
继续测试!将pid为18210的test也迁移到Cpu1上运行,执行:
Cpu0闲着,Cpu1忙碌起来了!
*/

void main(int argc, char** argv)  
{  
        for(int i = 0; i<=10000000000000; i++)  
        {  
                if(i == 100000000)  
                {  
                        i = 0;  
                        printf("program is running!\n");  
                }  
        }  
}  

线程绑定逻辑核:

CPU亲合力就是指在Linux系统中能够将一个或多个进程绑定到一个或多个处理器上运行.
一个进程的CPU亲合力掩码决定了该进程将在哪个或哪几个CPU上运行.在一个多处理器系统中,设置CPU亲合力的掩码可能会获得更好的性能.

一个CPU的亲合力掩码用一个cpu_set_t结构体来表示一个CPU集合,下面的几个宏分别对这个掩码集进行操作:
·CPU_ZERO() 清空一个集合
·CPU_SET()与CPU_CLR()分别对将一个给定的CPU号加到一个集合或者从一个集合中去掉.
·CPU_ISSET()检查一个CPU号是否在这个集合中.

下面两个函数就是用来设置获取线程CPU亲和力状态:
·sched_setaffinity(pid_t pid, unsigned int cpusetsize, cpu_set_t *mask)
该函数设置进程为pid的这个进程,让它运行在mask所设定的CPU上.如果pid的值为0,则表示指定的是当前进程,使当前进程运行在mask所设定的那些CPU上.第二个参数cpusetsize是mask所指定的数的长度.通常设定为sizeof(cpu_set_t).如果当前pid所指定的进程此时没有运行在mask所指定的任意一个CPU上,则该指定的进程会从其它CPU上迁移到mask的指定的一个CPU上运行.
·sched_getaffinity(pid_t pid, unsigned int cpusetsize, cpu_set_t *mask)
该函数获得pid所指示的进程的CPU位掩码,并将该掩码返回到mask所指向的结构中.即获得指定pid当前可以运行在哪些CPU上.同样,如果pid的值为0.也表示的是当前进程

cpu_set_t的定义  

# define __CPU_SETSIZE 1024  
# define __NCPUBITS (8 * sizeof (__cpu_mask))  
typedef unsigned long int __cpu_mask;  
# define __CPUELT(cpu) ((cpu) / __NCPUBITS)  
# define __CPUMASK(cpu) ((__cpu_mask) 1 << ((cpu) % __NCPUBITS))  
typedef struct  
{  
__cpu_mask __bits[__CPU_SETSIZE / __NCPUBITS];  
} cpu_set_t;  

# define __CPU_ZERO(cpusetp) \  
do { \  
unsigned int __i; \  
cpu_set_t *__arr = (cpusetp); \  
for (__i = 0; __i < sizeof (cpu_set_t) / sizeof (__cpu_mask); ++__i) \  
__arr->__bits[__i] = 0; \  
} while (0)  
# define __CPU_SET(cpu, cpusetp) \  
((cpusetp)->__bits[__CPUELT (cpu)] |= __CPUMASK (cpu))  
# define __CPU_CLR(cpu, cpusetp) \  
((cpusetp)->__bits[__CPUELT (cpu)] &= ~__CPUMASK (cpu))  
# define __CPU_ISSET(cpu, cpusetp) \  
(((cpusetp)->__bits[__CPUELT (cpu)] & __CPUMASK (cpu)) != 0)  

测试代码:

#include<stdlib.h>  
#include<stdio.h>  
#include<sys/types.h>  
#include<sys/sysinfo.h>  
#include<unistd.h>  

#define __USE_GNU  
#include<sched.h>  
#include<ctype.h>  
#include<string.h>  
#include<pthread.h>  
#define THREAD_MAX_NUM 100  //1个CPU内的最多进程数  

int num=0;  //cpu中核数  
void* threadFun(void* arg)  //arg  传递线程标号(自己定义)  
{  
         cpu_set_t mask;  //CPU核的集合  
         cpu_set_t get;   //获取在集合中的CPU  
         int *a = (int *)arg;   
         printf("the a is:%d\n",*a);  //显示是第几个线程  
         CPU_ZERO(&mask);    //置空  
         CPU_SET(*a,&mask);   //设置亲和力值  
         if (sched_setaffinity(0, sizeof(mask), &mask) == -1)//设置线程CPU亲和力  
         {  
                   printf("warning: could not set CPU affinity, continuing...\n");  
         }  
         while (1)  
         {  
                   CPU_ZERO(&get);  
                   if (sched_getaffinity(0, sizeof(get), &get) == -1)//获取线程CPU亲和力  
                   {  
                            printf("warning: cound not get thread affinity, continuing...\n");  
                   }  
                   int i;  
                   for (i = 0; i < num; i++)  
                   {  
                            if (CPU_ISSET(i, &get))//判断线程与哪个CPU有亲和力  
                            {  
                                     printf("this thread %d is running processor : %d\n", i,i);  
                            }  
                   }  
         }  

         return NULL;  
}  

int main(int argc, char* argv[])  
{  
         num = sysconf(_SC_NPROCESSORS_CONF);  //获取核数  
         pthread_t thread[THREAD_MAX_NUM];  
         printf("system has %i processor(s). \n", num);  
         int tid[THREAD_MAX_NUM];  
         int i;  
         for(i=0;i<num;i++)  
         {  
                   tid[i] = i;  //每个线程必须有个tid[i]  
                   pthread_create(&thread[0],NULL,threadFun,(void*)&tid[i]);  
         }  
         for(i=0; i< num; i++)  
         {  
                   pthread_join(thread[i],NULL);//等待所有的线程结束,线程为死循环所以CTRL+C结束  
         }  
         return 0;  
}  

编译命令:gcc bind.c -o bind -lpthread
执行:./bind
输出结果:略

特别注意:

#define __USE_GNU不要写成#define _USE_GNU
#include<pthread.h>必须写在#define __USE_GNU之后,否则编译会报错

查看你的线程情况可以在执行时在另一个窗口使用top -H来查看线程的情况,查看各个核上的情况请使用top命令然后按数字“1”来查看。

<think>嗯,用户问的是如何在TensorFlow中获取CPU心个。我需要先回忆一下TensorFlow的相关API。记得在TensorFlow2.x中,有一些函可以列出物理设备,比如tf.config.list_physical_devices('CPU'),这个会返回所有可用的CPU设备,然后每个设备可能对应多个心?或者这个函返回的是设备量而不是?可能需要进一步确认。另外,用户可能需要的是获取系统的逻辑核,而不仅仅是设备量。比如,一个CPU可能有8个逻辑核心。这时候可能需要用其他方法,比如Python的multiprocessing模块或者psutil库来获取真实的。因为TensorFlow本身可能不直接提供,而是提供设备列表。 然后,用户的问题可能涉及到如何动态地根据来配置线程池,比如设置intra_op_threads和inter_op_threads。这时候需要结合TensorFlow的线程配置方法和系统获取方法。我应该分步骤来解决:首先,使用TensorFlow获取CPU设备量,但这可能只是设备个,比如在有多路CPU的情况下。然后,使用Python的其他库获取逻辑核。接着,给出一个综合的示例代码,展示如何获取并打印这些信息,并根据进行配置。 还需要注意,不同的操作系统可能有不同的方法获取,比如在Linux下可以通过os.sched_getaffinity来获取当前进程可用的。而multiprocessing.cpu_count()可能返回逻辑核,psutil.cpu_count(logical=True)也是类似的功能。最后,可能需要提醒用户,TensorFlow的线程配置和实际的之间的关系,如何合理设置线程以优化性能。例如,intra_op_threads通常设置为物理,而inter_op_threads根据任务类型调整。</think>在TensorFlow中获取CPU的完整解决方案如下,包含多种检测方式和应用场景: ```python import tensorflow as tf import multiprocessing import psutil import os def get_cpu_info(): """获取详细的CPU心信息""" # 方法1:通过TensorFlow获取物理CPU设备 tf_cpus = tf.config.list_physical_devices('CPU') # 方法2:使用Python标准库 py_cores = multiprocessing.cpu_count() # 方法3:使用psutil获取更详细信息 psutil_cores = { 'physical': psutil.cpu_count(logical=False), 'logical': psutil.cpu_count(logical=True) } # 方法4:Linux系统调用 sys_cores = len(os.sched_getaffinity(0)) if hasattr(os, 'sched_getaffinity') else None return { 'tensorflow_devices': len(tf_cpus), 'python_cores': py_cores, 'psutil_physical': psutil_cores['physical'], 'psutil_logical': psutil_cores['logical'], 'system_affinity': sys_cores } def configure_tf_by_cores(): """根据自动配置TensorFlow线程""" cores = get_cpu_info() # 设置线程池配置规则 intra_threads = cores['psutil_physical'] or 4 inter_threads = max(1, (cores['psutil_logical'] or 8) - intra_threads) tf.config.threading.set_intra_op_parallelism_threads(intra_threads) tf.config.threading.set_inter_op_parallelism_threads(inter_threads) print(f"自动配置完成:intra_op_threads={intra_threads}, inter_op_threads={inter_threads}") if __name__ == "__main__": # 打印所有CPU信息 cpu_info = get_cpu_info() print("CPU心信息:") print(f"TensorFlow识别的CPU设备: {cpu_info['tensorflow_devices']}") print(f"Python逻辑核: {cpu_info['python_cores']}") print(f"物理心/逻辑核心: {cpu_info['psutil_physical']}/{cpu_info['psutil_logical']}") print(f"系统亲和性: {cpu_info['system_affinity']}") # 自动配置TensorFlow configure_tf_by_cores() # 验证配置 print("\n当前TensorFlow线程配置:") print(f"Intra-op threads: {tf.config.threading.get_intra_op_parallelism_threads()}") print(f"Inter-op threads: {tf.config.threading.get_inter_op_parallelism_threads()}") ``` 方法说明: 1. **TensorFlow物理设备检测**: ```python tf.config.list_physical_devices('CPU') ``` 返回物理CPU设备列表(通常单个CPU返回1个设备对象) 2. **多维度心检测**: - `multiprocessing.cpu_count()`:获取逻辑核 - `psutil`提供物理/逻辑核心的精确区分 - `os.sched_getaffinity`获取当前进程可用的Linux专用) 3. **智能配置策略**: - intra_op_threads = 物理 - inter_op_threads = 逻辑核 - 物理 这种配置方式可以充分利用CPU的并行能力 典型输出示例: ``` CPU心信息: TensorFlow识别的CPU设备: 1 Python逻辑核: 16 物理心/逻辑核心: 8/16 系统亲和性: 16 自动配置完成:intra_op_threads=8, inter_op_threads=8 当前TensorFlow线程配置: Intra-op threads: 8 Inter-op threads: 8 ``` 高级应用场景: ```python # 动态调整据管道并行度 dataset = tf.data.Dataset.range(100) dataset = dataset.map( lambda x: x**2, num_parallel_calls=tf.data.AUTOTUNE # 自动根据优化 ) # 绑定CPU亲和性(需要TensorFlow 2.9+) if tf.__version__ >= '2.9.0': tf.config.threading.set_cpu_affinity(['/cpu:0', '/cpu:1']) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值