怎么用脚本获取处理器拓扑

wen 实用脚本 1

本文目录导读:

怎么用脚本获取处理器拓扑

  1. 使用 Python(跨平台)
  2. 使用 Shell 脚本(Linux/macOS)
  3. 使用 PowerShell(Windows)
  4. 使用 Python 的 psutil 库(跨平台)
  5. 使用 lscpu 命令格式输出(Linux)
  6. 推荐方案

获取处理器拓扑(如核心、线程、缓存、NUMA节点等)可以通过多种语言的脚本实现,以下是常用方法:

使用 Python(跨平台)

基础拓扑信息

import platform
import os
def get_cpu_topology():
    info = {}
    # 逻辑处理器数量
    try:
        import multiprocessing
        info['logical_cpus'] = multiprocessing.cpu_count()
    except:
        pass
    # 操作系统信息
    info['system'] = platform.system()
    info['architecture'] = platform.machine()
    # Windows 特殊处理
    if info['system'] == 'Windows':
        info['physical_cpus'] = int(os.environ.get('NUMBER_OF_PROCESSORS', 0))
        # 更多细节需要 WMI
        try:
            import wmi
            c = wmi.WMI()
            for cpu in c.Win32_Processor():
                info['name'] = cpu.Name
                info['cores'] = cpu.NumberOfCores
                info['logical_per_core'] = int(cpu.NumberOfLogicalProcessors) // int(cpu.NumberOfCores)
        except ImportError:
            pass
    return info
print(get_cpu_topology())

详细拓扑(Linux)

import os
def parse_linux_cpu_topology():
    """解析Linux /sys 文件系统获取处理器拓扑"""
    topology = {
        'packages': {},
        'cores': {},
        'caches': {}
    }
    cpu_dir = '/sys/devices/system/cpu'
    # 遍历所有CPU
    for cpu in os.listdir(cpu_dir):
        if not cpu.startswith('cpu') or not cpu[3:].isdigit():
            continue
        cpu_id = cpu[3:]
        cpu_path = os.path.join(cpu_dir, cpu)
        # 检查是否在线
        online_path = os.path.join(cpu_path, 'online')
        if os.path.exists(online_path):
            with open(online_path) as f:
                if f.read().strip() != '1':
                    continue
        # 获取拓扑信息
        topology_path = os.path.join(cpu_path, 'topology')
        # 物理包ID
        with open(os.path.join(topology_path, 'physical_package_id')) as f:
            pkg_id = f.read().strip()
        # 核心ID
        with open(os.path.join(topology_path, 'core_id')) as f:
            core_id = f.read().strip()
        # 核心类型
        try:
            with open(os.path.join(topology_path, 'core_types')) as f:
                core_type = f.read().strip()
        except FileNotFoundError:
            core_type = 'unknown'
        # 更新拓扑结构
        if pkg_id not in topology['packages']:
            topology['packages'][pkg_id] = {'cpu_list': []}
        core_key = f"pkg{pkg_id}_core{core_id}"
        if core_key not in topology['cores']:
            topology['cores'][core_key] = {'package_id': pkg_id, 'core_id': core_id, 'threads': []}
        topology['cores'][core_key]['threads'].append(cpu_id)
        topology['packages'][pkg_id]['cpu_list'].append(cpu_id)
    # 获取缓存信息
    for cpu in os.listdir(cpu_dir):
        if not cpu.startswith('cpu'):
            continue
        cpu_path = os.path.join(cpu_dir, cpu, 'cache')
        if os.path.exists(cpu_path):
            for index in os.listdir(cpu_path):
                if index.startswith('index'):
                    idx_path = os.path.join(cpu_path, index)
                    level = open(os.path.join(idx_path, 'level')).read().strip()
                    policy = open(os.path.join(idx_path, 'policy')).read().strip()
                    size = open(os.path.join(idx_path, 'size')).read().strip()
                    cache_key = f"L{level}_{index}"
                    if cache_key not in topology['caches']:
                        topology['caches'][cache_key] = {'level': level, 'policy': policy, 'size': size}
    return topology
topology = parse_linux_cpu_topology()
for pkg, info in topology['packages'].items():
    print(f"Package {pkg}: CPUs {info['cpu_list']}")
for core, info in topology['cores'].items():
    print(f"Core {core}: Threads {info['threads']}")

使用 Shell 脚本(Linux/macOS)

基础命令

# 查看CPU信息
lscpu | head -20
# 物理CPU数量
echo "物理CPU数:"
grep "physical id" /proc/cpuinfo | sort -u | wc -l
# 物理核心数
echo "物理核心数:"
grep "core id" /proc/cpuinfo | sort -u | wc -l
# 逻辑核心数
echo "逻辑核心数:"
grep "processor" /proc/cpuinfo | wc -l
# 每个物理核心的线程数
echo "每核心线程数:"
echo $(( $(nproc) / $(grep "core id" /proc/cpuinfo | sort -u | wc -l) ))

详细拓扑脚本

#!/bin/bash
echo "=== 处理器拓扑 ==="
echo ""
# 获取每个CPU的拓扑信息
echo "CPU 拓扑映射:"
echo "CPU | 父包 | 核心ID | 核心类型"
for cpu in /sys/devices/system/cpu/cpu[0-9]*; do
    if [ -f "$cpu/online" ] && [ "$(cat $cpu/online)" != "1" ]; then
        continue
    fi
    cpu_id=$(basename $cpu | sed 's/cpu//')
    pkg_id=$(cat $cpu/topology/physical_package_id 2>/dev/null || echo "N/A")
    core_id=$(cat $cpu/topology/core_id 2>/dev/null || echo "N/A")
    echo "CPU $cpu_id | Package $pkg_id | Core $core_id"
done
echo ""
echo "=== 缓存拓扑 ==="
for cpu in /sys/devices/system/cpu/cpu[0-9]*; do
    cpu_id=$(basename $cpu | sed 's/cpu//')
    cache_info=$(cat $cpu/topology/cache_index0 2>/dev/null)
    echo "CPU $cpu_id: $cache_info"
done
echo ""
echo "=== NUMA 节点 ==="
numactl --hardware 2>/dev/null || echo "numactl not installed"

使用 PowerShell(Windows)

# 使用 WMI 获取处理器信息
$cpus = Get-WmiObject Win32_Processor
foreach ($cpu in $cpus) {
    Write-Host "CPU: $($cpu.Name)"
    Write-Host "  Cores: $($cpu.NumberOfCores)"
    Write-Host "  Logical Processors: $($cpu.NumberOfLogicalProcessors)"
    Write-Host "  Socket Designation: $($cpu.SocketDesignation)"
    # 每核心线程数
    $threads_per_core = $cpu.NumberOfLogicalProcessors / $cpu.NumberOfCores
    Write-Host "  Threads per Core: $threads_per_core"
}
# 使用 Get-CimInstance 获取更详细的信息
$cim_cpus = Get-CimInstance -ClassName CIM_Processor
foreach ($cpu in $cim_cpus) {
    Write-Host "`nCPU Details:"
    Write-Host "  Manufacturer: $($cpu.Manufacturer)"
    Write-Host "  Max Clock Speed: $($cpu.MaxClockSpeed) MHz"
    Write-Host "  Architecture: $($cpu.Architecture)"
}

使用 Python 的 psutil 库(跨平台)

import psutil
def get_detailed_topology():
    info = {}
    # 获取CPU数量
    info['physical_cores'] = psutil.cpu_count(logical=False)
    info['logical_cores'] = psutil.cpu_count(logical=True)
    # CPU 频率
    freq = psutil.cpu_freq()
    info['current_freq'] = freq.current if freq else None
    info['max_freq'] = freq.max if freq else None
    # 每个核心的使用情况
    info['per_cpu_percent'] = psutil.cpu_percent(percpu=True, interval=1)
    return info
info = get_detailed_topology()
print(f"物理核心: {info['physical_cores']}")
print(f"逻辑核心: {info['logical_cores']}")
print(f"CPU频率: {info['current_freq']} MHz")

使用 lscpu 命令格式输出(Linux)

# 解析lscpu为JSON格式
lscpu --json 2>/dev/null || lscpu
# 或者解析为可读格式
lscpu --parse=CORE,CPU,PACKAGE 2>/dev/null || lscpu --parse
# 使用特定格式
lscpu --extended

推荐方案

  • Linux/Unix: 使用 lscpu 或解析 /sys 文件系统
  • Windows: 使用 PowerShell + WMI
  • 跨平台脚本: Python + psutil
  • 快速查看: 直接使用系统命令

这些方法可以获取处理器拓扑的详细信息,包括核心、线程、缓存层次结构和NUMA拓扑。

抱歉,评论功能暂时关闭!