单个文件实现cpu的信息检测:ruapu.h的学习笔记

news/发布时间2024/5/16 5:49:17
  • https://github.com/nihui/ruapu是nihui大佬开发的用单文件检测CPU特性的项目

ruapu.h的使用

  • "ruapu.h"主要提供了两个函数 ruapu_init 和 ruapu_supports,分别用于初始化和检测指令集支持。
// 使用示例见:https://github1s.com/nihui/ruapu/blob/master/main.c#L14-L16
void ruapu_init();
int ruapu_supports(const char* isa);

使用方式

#define RUAPU_IMPLEMENTATION
#include "ruapu.h"
  • 需要加上 #define RUAPU_IMPLEMENTATION是因为"ruapu.h"的结构如下(一般来说头文件只包含声明,所以要这样处理)
#ifndef RUAPU_H
#define RUAPU_Hvoid ruapu_init();
int ruapu_supports(const char* isa);#ifdef RUAPU_IMPLEMENTATION// 两个函数的实现
#endif // RUAPU_IMPLEMENTATION

实现部分

#include <setjmp.h>
#include <string.h>

Windows 平台的ruapu_detect_isa()实现

#if defined _WIN32
#include <windows.h>#if WINAPI_FAMILY == WINAPI_FAMILY_APP
// uwp does not support veh :(   UWP平台不支持VEH(Vectored Exception Handling)
#if defined (_MSC_VER)
#pragma message("warning: ruapu does not support UWP yet.")
#else
#warning ruapu does not support UWP yet.
#endif
static int ruapu_detect_isa(const void* some_inst)// 该函数总是返回0
{(void)some_inst;return 0;
}
#else // WINAPI_FAMILY == WINAPI_FAMILY_APP
// 如果不是UWP平台,这里放置非UWP平台的ruapu_detect_isa()实现
#endif // WINAPI_FAMILY == WINAPI_FAMILY_APP

Android、Linux、和 macOS 平台的ruapu_detect_isa()实现

#elif defined __ANDROID__ || defined __linux__ || defined __APPLE__
#include <signal.h>
// ruapu_detect_isa()通过模拟异常处理的方式,检测特定指令集的支持情况,当执行包含该指令集的代码时,通过捕捉非法指令信号来判断是否支持
#endif // defined _WIN32 || defined __ANDROID__ || defined __linux__ || defined __APPLE__

ruapu_detect_isa()在Android、Linux、和 macOS 平台实现的具体代码

#include <signal.h>// 全局变量,用于标志是否捕获到 SIGILL 信号
static int g_ruapu_sigill_caught = 0;// 全局变量,用于保存跳转的上下文信息
static sigjmp_buf g_ruapu_jmpbuf;// 定义一个函数指针类型,表示一些指令的执行函数
typedef void (*ruapu_some_inst)();// SIGILL 信号捕获处理函数
static void ruapu_catch_sigill(int signo, siginfo_t* si, void* data)
{// 防止未使用的参数警告(void)signo;(void)si;(void)data;// 标志捕获到 SIGILL 信号g_ruapu_sigill_caught = 1;// 跳转到之前保存的上下文信息,值为 -1 表示异常跳转siglongjmp(g_ruapu_jmpbuf, -1);
}// 检测指令集支持的函数,输入是一个指令组成的数组比如:{0xc5, 0xfc, 0x54, 0xc0, 0xC3 },关于数组的来源可以先看下面的部分
static int ruapu_detect_isa(ruapu_some_inst some_inst)
{// 初始化捕获到 SIGILL 的标志为 0g_ruapu_sigill_caught = 0;// 定义 sigaction 结构体,用于设置信号处理函数struct sigaction sa = { 0 };struct sigaction old_sa;// 设置信号处理函数为 ruapu_catch_sigillsa.sa_flags = SA_ONSTACK | SA_RESTART | SA_SIGINFO;sa.sa_sigaction = ruapu_catch_sigill;// 设置 SIGILL 信号的处理函数,并保存之前的处理函数信息sigaction(SIGILL, &sa, &old_sa);// 通过 setjmp 在此处保存当前上下文信息,并返回 0 表示正常执行if (sigsetjmp(g_ruapu_jmpbuf, 1) == 0){// 执行一些指令,如果有非法指令,会跳转到 catch 处理some_inst();}// 恢复 SIGILL 信号的原始处理函数sigaction(SIGILL, &old_sa, NULL);// 返回捕获到 SIGILL 信号的标志,如果捕获到返回 0,否则返回 1return g_ruapu_sigill_caught ? 0 : 1;
}

RUAPU_INSTCODE宏

  • 然后是为不同平台定义RUAPU_INSTCODE宏,比如在windows平台(_WIN32),x86_64架构(__x86_64__),Microsoft Visual Studio 编译器(_MSC_VER
#define RUAPU_INSTCODE(isa, ...) __pragma(section(".text")) __declspec(allocate(".text")) static unsigned char ruapu_some_##isa[] = { __VA_ARGS__, 0xc3 };
  • 展开为:
#define RUAPU_INSTCODE(isa, ...) \__pragma(section(".text"))    \__declspec(allocate(".text")) \static unsigned char ruapu_some_##isa[] = { __VA_ARGS__, 0xc3 };
  • 使用这个宏调用RUAPU_INSTCODE(avx, 0xc5, 0xfc, 0x54, 0xc0);将会被预处理器替换成以下代码:
__pragma(section(".text")) 
__declspec(allocate(".text")) 
static unsigned char ruapu_some_AVX[] = {0xc5, 0xfc, 0x54, 0xc0, 0xC3 }; // ## 是C语言宏中的连接操作符
  • 然后就能创建了一堆名为 ruapu_some_isa 的静态无符号字符数组
RUAPU_INSTCODE(mmx, 0x0f, 0xdb, 0xc0) // pand mm0,mm0
RUAPU_INSTCODE(sse, 0x0f, 0x54, 0xc0) // andps xmm0,xmm0
RUAPU_INSTCODE(avx, 0xc5, 0xfc, 0x54, 0xc0);// vandps ymm0,ymm0,ymm0

RUAPU_ISAENTRY宏

  • 然后用RUAPU_ISAENTRY宏来定义了g_ruapu_isa_map的结构体数组
struct ruapu_isa_entry
{const char* isa;ruapu_some_inst inst;int capable;
};#define RUAPU_ISAENTRY(isa) { #isa, (ruapu_some_inst)ruapu_some_##isa, 0 },struct ruapu_isa_entry g_ruapu_isa_map[] = {RUAPU_ISAENTRY(mmx)
RUAPU_ISAENTRY(sse)
RUAPU_ISAENTRY(sse2)
RUAPU_ISAENTRY(sse3)
RUAPU_ISAENTRY(ssse3)
RUAPU_ISAENTRY(sse41)}

两个函数的最终实现

void ruapu_init()
{// 如果是在支持的操作系统下(Windows、Android、Linux、macOS等)
#if defined _WIN32 || defined __ANDROID__ || defined __linux__ || defined __APPLE__// 遍历 g_ruapu_isa_map 数组for (size_t i = 0; i < sizeof(g_ruapu_isa_map) / sizeof(g_ruapu_isa_map[0]); i++){// 调用 ruapu_detect_isa 函数检测指令集支持情况,并将结果存储在 g_ruapu_isa_map[i].capable 中g_ruapu_isa_map[i].capable = ruapu_detect_isa(g_ruapu_isa_map[i].inst);}
#else// 如果操作系统不是上述支持的操作系统// 在此处初始化 g_ruapu_isa_map 数组,默认全部为零// 仍然可以使用 ruapu_some_XYZ() 函数// 但是你需要自己处理信号// 发出编译警告,说明 ruapu 还不支持当前裸机操作系统
#warning ruapu does not support your baremetal os yet
#endif
}int ruapu_supports(const char* isa)
{// 遍历 g_ruapu_isa_map 数组for (size_t i = 0; i < sizeof(g_ruapu_isa_map) / sizeof(g_ruapu_isa_map[0]); i++){// 检查是否有与输入指令集名称匹配的条目if (strcmp(g_ruapu_isa_map[i].isa, isa) == 0){// 如果找到匹配的指令集,返回相应的 capable 值return g_ruapu_isa_map[i].capable;}}// 如果没有找到匹配的指令集,返回0表示不支持return 0;
}

CG

  • Cpu-z由Cpuid提供是一个免费的系统信息软件,它收集有关计算机主要装置的信息。 它报告数据,如处理器名称和号码、代号、过程、包装、高速缓存水平、主板和芯片详情(如内存类型、大小、时序和SPD)。 这个应用可以实时测量核心内部频率和内存频率。 通过Google Playstore在Windows 系列电脑上也能使用.
  • https://github.com/pytorch/cpuinfo

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.bcls.cn/WAKR/4168.shtml

如若内容造成侵权/违法违规/事实不符,请联系编程老四网进行投诉反馈email:xxxxxxxx@qq.com,一经查实,立即删除!

相关文章

apidoc接口文档的自动更新与发布

文章目录 一、概述二、环境准备三、接口文档生成1. 下载源码2. 初始化3.执行 四、文档发布五&#xff0c;配置定时运行六&#xff0c;docker运行 一、概述 最近忙于某开源项目的接口文档整理&#xff0c;采用了apidoc来整理生成接口文档。 apidoc是一个可以将源代码中的注释直…

AWS安全组是什么?有什么用?

最近看到小伙伴在问&#xff0c;AWS安全组是什么&#xff1f;有什么用&#xff1f;今天我们大家就来简单聊聊&#xff0c;仅供参考哦&#xff01; AWS安全组是什么&#xff1f;有什么用&#xff1f; 【回答】&#xff1a;AWS安全组是一种虚拟防火墙&#xff0c;用于控制进出…

Zookeeper特性与节点数据类型详解

Zookeeper特性与节点数据类型详解 Zookeeper简介 一个基于观察者模式&#xff0c;主要是用来解决分布式集群应用系统一致性问题的协调框架&#xff0c;基于CP机制 本质是一个分布式的小文件存储系统(文件系统监听机制)提供基于类似于文件系统的目录树方式的数据存储&#xff…

Git合并固定分支的某一部分至当前分支

在 Git 中&#xff0c;通常使用 git merge 命令来将一个分支的更改合并到另一个分支。如果你只想合并某个分支的一部分代码&#xff0c;可以使用以下两种方法&#xff1a; 1.批量文件合并 1.1.创建并切换到一个新的临时分支 首先&#xff0c;从要合并的源分支&#xff08;即要…

Maven的下载安装配置教程

一、简单了解一下什么是Maven Maven就是一款帮助程序员构建项目的工具&#xff0c;我们只需要告诉Maven需要哪些Jar 包&#xff0c;它会帮助我们下载所有的Jar&#xff0c;极大提升开发效率。 1.Maven翻译为“专家“&#xff0c; ”内行”的意思&#xff0c;是著名Apache公司下…

ElasticSearch索引数据备份与恢复

索引数据备份 在磁盘创建备份目录并授权 # 创建备份目录 /home/esbackup # 授权 chmod 777 /home/esbackup修改配置文件elasticsearch.yml echo path.repo: ["/home/esbackup"] >> /etc/elasticsearch/elasticsearch.yml重启elasticsearch(我是docker创建的…

矿产达人小程序修复前端

应用介绍 本文来自&#xff1a;矿产达人小程序修复前端 - 源码1688 矿产达人小程序&#xff1a; 矿产小游戏小程序是一款以矿产资源为主题的休闲娱乐游戏。以下是该小程序的主要功能特点&#xff1a; 游戏画面精美&#xff1a;小程序采用卡通化的设计风格&#xff0c;画面色…

【操作系统】磁盘存储空间的管理

实验5 磁盘存储空间的管理 一、实验目的 磁盘是用户存放程序和数据的存储设备&#xff0c;磁盘管理的主要目的是充分有效地利用磁盘空间。本实验模拟实现磁盘空间的分配与回收&#xff0c;使学生对磁盘空间的管理有一个较深入的理解。 二、实验内容 实验任务&#xff1a;用位…

记录 | docker内执行apt update报错GPG error

1. 执行 sudo apt-get update 命令时遇到这个错误&#xff0c;是服务器没有这个公钥的意思 rootadmin:~# sudo apt-get update Get:1 https://download.docker.com/linux/ubuntu focal InRelease [36.2 kB] Err:1 https://download.docker.com/linux/ubuntu focal InRelease T…

Redis 分布式锁

什么是分布式锁 在一个分布式的系统中&#xff0c;也会涉及到多个节点访问同一个公共资源的情况。此时就需要通过锁来做互斥控制&#xff0c;避免出现类似于“线程安全”的问题。 而 java 的 synchronized 或者 C 的 std::mutex&#xff0c;这样的锁都是只能在当前进程中生效…

基于yolov5的工地安全帽检测,可进行图像目标检测,也可进行视屏和摄像检测(pytorch框架)【python源码+UI界面+功能源码详解】

功能演示&#xff1a; 基于yolov5的工地安全帽检测系统&#xff0c;支持图像检测&#xff0c;视频检测和实时摄像检测功能_哔哩哔哩_bilibili &#xff08;一&#xff09;简介 基于yolov5的工地安全帽检测系统是在pytorch框架下实现的&#xff0c;这是一个完整的项目&#x…

oppo手机如何录屏?解锁录屏新功能!

“最近换了一款oppo手机&#xff0c;感觉它的拍照功能真的很强大。但除此之外&#xff0c;我发现oppo还有许多隐藏功能&#xff0c;比如录屏。但我尝试了很久&#xff0c;都没找到录屏的开关在哪里。有没有哪位oppo用户知道怎么打开这个功能呢&#xff1f;” 随着科技的不断发…

WebStorm 2023:让您更接近理想的开发环境 mac/win版

JetBrains WebStorm 2023激活版下载是一款强大而智能的Web开发工具&#xff0c;专为提高开发人员的生产力而设计。这款编辑器提供了许多先进的代码编辑功能&#xff0c;以及一系列实用的工具和插件&#xff0c;可帮助您更快地编写、调试和测试代码。 WebStorm 2023软件获取 We…

torch.nn.embedding的介绍和用法

nn.Embedding 是 PyTorch 中的一个神经网络层&#xff0c;它主要用于将离散的、高维的数据&#xff08;如词索引&#xff09;转换为连续的、低维的空间中的稠密向量表示。在自然语言处理&#xff08;NLP&#xff09;中&#xff0c;这个层通常用于实现词嵌入&#xff08;Word Em…

高级RAG:揭秘PDF解析

原文地址&#xff1a;https://pub.towardsai.net/advanced-rag-02-unveiling-pdf-parsing-b84ae866344e 2024 年 2 月 3 日 附加内容&#xff1a;揭秘PDF解析&#xff1a;如何从科学pdf论文中提取公式 对于RAG&#xff0c;从文档中提取信息是一个不可避免的场景。确保从源头…

c++的类型转换方法

一、静态类型转换&#xff08;static_cast&#xff09; 静态类型的转换主要用于基本类型之间的转换&#xff0c;比如int类型转换为double类型。但是static_cast也可以支持上下行的转换&#xff08;存在继承关系之间的转换&#xff09; 基本类型之间的转换举例 上下行转换的举…

IDEA 2023.2 配置 JavaWeb 工程

目录 1 不使用 Maven 创建 JavaWeb 工程 1.1 新建一个工程 1.2 配置 Tomcat 1.3 配置模块 Web 2 使用 Maven 配置 JavaWeb 工程 2.1 新建一个 Maven 工程 2.2 配置 Tomcat &#x1f4a5;提示&#xff1a;IDEA 只有专业版才能配置 JavaWeb 工程&#xff0c;若是社区版&am…

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的犬种识别系统(附完整代码资源+UI界面+PyTorch代码)

摘要&#xff1a;本文介绍了一种基于深度学习的犬种识别系统系统的代码&#xff0c;采用最先进的YOLOv8算法并对比YOLOv7、YOLOv6、YOLOv5等算法的结果&#xff0c;能够准确识别图像、视频、实时视频流以及批量文件中的犬种。文章详细解释了YOLOv8算法的原理&#xff0c;并提供…

【方法】PDF如何与其它格式文件互相转换?

在工作上&#xff0c;有时候我们需要把PDF文件转换成其他格式的文件&#xff0c;比如Word、PPT、jpg等&#xff0c;或者是其他格式文件转换成PDF&#xff0c;那具体要如何操作呢&#xff1f;不清楚的小伙伴一起来看看吧&#xff01; 想把PDF文件转换成其他格式文件&#xff0c…

SQL表(字段)操作

目标&#xff1a;掌握数据库和字段的相关操作指令&#xff0c;熟练运用这些指令完成数据表的增删改查 创建数据表 显示数据库 查看表结构 更改数据表 更改字段 删除数据表 1、创建数据表 目标&#xff1a;了解数据表创建语法&#xff0c;掌握创建规则 概念 创建数据表:根…
推荐文章