Linux 应用程序CPU调度优化

缘起

       实时操作系统(Real-time operating system, RTOS),又称即时操作系统,它会按照排序运行、管理系统资源,并为开发应用程序提供一致的基础。实时操作系统与一般的操作系统相比,最大的特色就是实时性,如果有一个任务需要执行,实时操作系统会马上(在较短时间内)执行该任务,不会有较长的延时。这种特性保证了各个任务的及时执行。
      经常跟实时操作系统一起讲的,还有嵌入式操作系统这个概念,但实际上这是完全不同的两种东西,虽然大多数实时操作系统都是嵌入式操作系统,但嵌入式操作系统并不全都是实时的。
      对于实时操作系统有一些常见的误区,比如:速度快,吞吐量大,代码精简,代码规模小等等。其实这些都不算是实时操作系统的特性,别的操作系统也可以做到。只有实时性才是RTOS的最大特征,其它的都不算是。

       在了解了关于实时的概念后, 对于以下说描述的问题相对会更好理解一点. 本文采用的平台是RK3588 + Linux, 运行非实时操作系统编写一个C++程序, 用于从陀螺仪中读取数据并写入文件中, 陀螺仪的采样频率为 2000HZ, 也就是说0.5MS采样一次, 文件中写一行. 通过优化应用程序的CPU调度, 提高应用程序相应的实时性, 尽量接近实时操作系统.
在这里插入图片描述

过程

神奇的现象: 频繁地打印时间间隔反而缩小了!

	char buff[32];
	while(true){
		size_t read = read(fd, buff, 32);
		//-----------打印-------------
		//---------------------------
	}

打印的方式有两种, 一种是次循环里都有打印, 另一种是每个 1秒打印一次.

方式帧率
每次循环2000HZ
隔一秒1500-1900HZ

多次测试后,结果依旧, 为了保证输出的稳定性, 于是做了一些尝试, 其中一种方法就是提高线程的优先级
提高线程的优先级可以影响线程的调度顺序,使其在竞争资源时更有可能获得CPU时间片.

	pthread_t thread = pthread_self(); // 获取底层线程句柄
    struct sched_param param;
    param.sched_priority = sched_get_priority_max(SCHED_FIFO);
    if (pthread_setschedparam(thread, SCHED_FIFO, &param) != 0) {
        std::cerr << "无法设置线程的优先级" << std::endl;
    }

很幸运, 方法有效.

在前面读取数据的基础上, 加上了写入文件, 记录数据的功能, 整体性能和稳定性下降明显

原因有两个

  1. 主控运行在性能自动调节模式
  2. 程序运行在低性能的小核

第一点很好解决: 参考RK3588 CPU GPU DDR NPU定频和性能模式设置 设置高性能模式即可.
在这里插入图片描述


第二点需要用到taskset, 参考Linux性能优化(十五)——CPU绑定
     taskset用来查看和设定“CPU亲和力”,说白了就是查看或者配置进程和cpu的绑定关系,让某进程在指定的CPU核上运行,即是“绑核”。
RK3588: CPU – 4x Cortex-A76 @ 2.4/2.6 GHz和 4x Cortex-A55 内核@ 1.8 GHz, 4个大核, 4个小核.
需注意的是, 4个小核在0-3, 4个大核在4-7, 刚开始使用taskset是一直设置在小核上, 导致修改后效果不明显.

  • 指定CPU运行程序:
#程序运行在 CPU 7上.
taskset -c 7 /my_program
  • 修改运行中的程序
#修改指定进程运行到 CPU 7 上
taskset -pc 7 pid

修改后可以通过命令查看, 参考判断Linux进程在哪个CPU核运行的4个方法

## 方法1
$ taskset -cp pid
pid pid's current affinity list: 0-15

## 方法2
$ ps -eo pid,cmd,psr 4597
   4597 cat                          15

Timer 与 Thread 的sleep

为了稳定帧率, 减少帧误差, 稳定采样间隔在0.5MS, 尝试使用了线程和定时器的方法, 从测试结果看定时器的精度跟高

#include <stdio.h>
#include <sys/time.h>
#include <string.h>
#include <signal.h>
#include <time.h> 


void  handle(union sigval v){
    time_t t;
    char p[32];
    time(&t);
    strftime(p, sizeof(p), "%T", localtime(&t));
    printf("%s thread %lu, val = %d, signal captured.\n", p, pthread_self(), v.sival_int);
    return;
}

int main(int argc, char *argv[]){

    struct sigevent evp;
    struct itimerspec ts;
    timer_t timer;
    int ret;
    memset   (&evp, 0, sizeof(evp));
    evp.sigev_value.sival_ptr = &timer;
    evp.sigev_notify = SIGEV_THREAD;
    evp.sigev_notify_function = handle;
    evp.sigev_value.sival_int = 3;   //作为handle()的参数
    ret = timer_create(CLOCK_REALTIME, &evp, &timer);
    if( ret){
        perror("timer_create");
    }
   
    ts.it_interval.tv_sec = 1;
    ts.it_interval.tv_nsec = 0;
    ts.it_value.tv_sec = 3;
    ts.it_value.tv_nsec = 0;
    ret = timer_settime(timer, TIMER_ABSTIME, &ts, NULL);
    if( ret )
    {
        perror("timer_settime");
    }

    while(1);

}

结语

整个过程下来, 有效的优化有以下几点:

  1. 提高硬件工作频率, 如CPU, DDR, EMMC等
  2. 优化CPU调度, 把进程放到高性能的核上去运行
  3. 错开进程, 避免CPU资源抢占
  4. 提高线程优先级
  5. Timer的精确度优于 Thread 的 sleep

另外还有内核实时补丁方法,有待验证

---------------------------------------------------------

    “有更好的方法或建议, 欢迎不吝指教”

---------------------------------------------------------

引用

RK3588 CPU GPU DDR NPU定频和性能模式设置
判断Linux进程在哪个CPU核运行的4个方法
Linux性能优化(十五)——CPU绑定
什么是实时操作系统(RTOS)
Linux 系统上最常用的定时器

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

springboot maven项目环境搭建idea

springboot maven项目环境搭建idea 文章目录 springboot maven项目环境搭建idea用到的软件idea下载和安装java下载和安装maven下载和安装安装maven添加JAVA_HOME路径&#xff0c;增加JRE环境修改conf/settings.xml&#xff0c;请参考以下 项目idea配置打开现有项目run或build打…

【java学习—九】模板方法(TemplateMethod)设计模式(4)

文章目录 1. 在java中什么是模板2. 模板方法设计解决了什么问题&#xff1f;3. 代码化理解 1. 在java中什么是模板 抽象类体现的就是一种模板模式的设计&#xff0c;抽象类作为多个子类的通用模板&#xff0c;子类在抽象类的基础上进行扩展、改造&#xff0c;但子类总体上会保留…

C++STL---Vector、List所要掌握的基本知识

绪论​ 拼着一切代价&#xff0c;奔你的前程。 ——巴尔扎克&#xff1b;本章主要围绕vector和list的使用&#xff0c;以及容器底层迭代器失效问题&#xff0c;同时会有对原码的分析和模拟实现其底层类函数。​​​​话不多说安全带系好&#xff0c;发车啦&#xff08;建议电脑…

【Html】交通灯问题

效果 实现方式 计时器&#xff1a;setTimeout或setInterval来计时。setInterval和 setTimeout 在某些情况下可能会出现计时不准确的情况。这通常是由于JavaScript的事件循环机制和其他代码执行所需的时间造成的。 问询&#xff1a;通过getCurrentLight将每个状态的持续时间设置…

仿真软件Proteus8.10 SP3 pro一键安装、汉化教程(附proteus8.10下载链接安装视频)

本破解教程仅供个人及 proteus 8.10粉丝们交流学习之用&#xff0c;请勿用于商业用途&#xff0c; 谢谢支持。此版本为Proteus8.10 SP3 pro 这里写目录标题 安装包下载链接:视频教程 一、安装软件解压二、软件安装三、汉化 安装包下载链接: http://www.eemcu.cn/2022/05/14/pr…

vue3后台管理系统

项目创建及代码规范化开发 vue脚手架创建项目 安装vue脚手架 npm install-g vue/cli npm update -g vue/cli终端输入vue create 项目名称 即可进入模板选择 //利用vue-cli创建项目 进入模板选择 Vue CLI v5.0.8 ? Please pick a preset:Default ([Vue 3] babel, eslint)De…

Centos安装RabbitMQ,JavaSpring发送RabbitMQ延迟延时消息,JavaSpring消费RabbitMQ消息

1&#xff0c;版本说明 erlang 和 rabbitmq 版本说明 https://www.rabbitmq.com/which-erlang.html 确认需要安装的mq版本以及对应的erlang版本。 2&#xff0c;下载安装文件 RabbitMQ下载地址&#xff1a; https://packagecloud.io/rabbitmq/rabbitmq-server Erlang下载地…

exFAT文件系统的目录与文件存储

目录与文件存储的差异 在exFAT文件系统中&#xff0c;目录和文件的存储方式是不同的。 目录和文件都是以簇&#xff08;Cluster&#xff09;为单位进行存储&#xff0c;但它们的数据结构和用途不同。 目录的存储&#xff1a;目录&#xff08;子目录&#xff09;是用于组织和管…

Spring Boot进阶(93):体验式教程:手把手教你整合Spring Boot和Zipkin

&#x1f4e3;前言 分布式系统开发中&#xff0c;服务治理是一个比较重要的问题。为了更好地实现服务治理&#xff0c;需要解决服务跟踪问题&#xff0c;即如何对分布式系统中的服务进行监控和追踪。本文将介绍如何使用Zipkin进行服务跟踪&#xff0c;并结合Spring Boot进行整合…

解决cloudflare pages部署静态页面发生404错误的问题

cloudflare pages是一个非常方便的部署静态页面的sass工具。 但是很多人部署上去以后&#xff0c;访问服务会报404错误。什么原因&#xff1f; 原因如下图所示&#xff1a; 注意这个Build output directory, 这个是部署的关键&#xff01; 这个Build output directory目录的…

JVM性能优化 —— 类加载器,手动实现类的热加载

一、类加载的机制的层次结构 每个编写的”.java”拓展名类文件都存储着需要执行的程序逻辑&#xff0c;这些”.java”文件经过Java编译器编译成拓展名为”.class”的文件&#xff0c;”.class”文件中保存着Java代码经转换后的虚拟机指令&#xff0c;当需要使用某个类时&#…

虹科 | 解决方案 | 汽车示波器 索赔管理方案

索赔管理 Pico汽车示波器应用于主机厂/供应商与服务店/4S店的协作&#xff0c;实现产品索赔工作的高效管理&#xff1b;同时收集的故障波形数据&#xff0c;便于日后的产品优化和改进 故障记录 在索赔申请过程中&#xff0c;Pico汽车示波器的数据记录功能可以用于捕捉故障时的…

异步请求池——池式组件

前言 本文详细介绍异步请求池的实现过程&#xff0c;并使用DNS服务来测试异步请求池的性能。            两个必须牢记心中的概念&#xff1a; 同步&#xff1a;检测IO 与 读写IO 在同一个流程里异步&#xff1a;检测IO 与 读写IO 不在同一个流程 同步请求 与 异步请求…

聊聊“JVM 调优JVM 性能优化”是怎么个事?

所谓“调优”就是一个诊断和处理手段&#xff0c;最终的目标是让系统的处理能力&#xff0c;也就是“性能”达到最优化。 计算机系统中&#xff0c;性能相关的资源主要分为这几类&#xff1a; CPU&#xff1a;CPU 是系统最关键的计算资源&#xff0c;在单位时间内有限&#xf…

机器学习之查准率、查全率与F1

文章目录 查准率&#xff08;Precision&#xff09;&#xff1a;查全率&#xff08;Recall&#xff09;&#xff1a;F1分数&#xff08;F1 Score&#xff09;&#xff1a;实例P-R曲线F1度量python实现 查准率&#xff08;Precision&#xff09;&#xff1a; 定义&#xff1a; …

Unity中从3D模型资产中批量提取材质

如何使用 只需在“项目”窗口中创建一个名为“编辑器”的文件夹&#xff0c;然后在其中添加此脚本即可。然后&#xff0c;打开Window-Batch Extract Materials&#xff0c;配置参数并点击“ Extract&#xff01; ”。 在Unity 2019.1上&#xff0c;可以将默认材质重映射条件配…

RSA:基于小加密指数的攻击方式与思维技巧

目录 目录 目录 零、前言 一、小加密指数爆破 [FSCTF]RSA签到 思路&#xff1a; 二、基于小加密指数的有限域开根 [NCTF 2019]easyRSA 思路&#xff1a; 三、基于小加密指数的CRT [0CTF 2016] rsa 思路&#xff1a; 零、前言 最近&#xff0c;发现自己做题思路比较…

SpringCore完整学习教程5,入门级别

本章从第6章开始 6. JSON Spring Boot提供了三个JSON映射库的集成: Gson Jackson JSON-B Jackson是首选的和默认的库。 6.1. Jackson 为Jackson提供了自动配置&#xff0c;Jackson是spring-boot-starter-json的一部分。当Jackson在类路径上时&#xff0c;将自动配置Obj…

Java 将数据导出到Excel并发送到在线文档

一、需求 现将列表数据&#xff0c;导出到excel,并将文件发送到在线文档&#xff0c;摒弃了以往的直接在前端下载的老旧模式。 二、pom依赖 <!-- redission --><dependency><groupId>org.redisson</groupId><artifactId>redisson-spring-boot-…

UE5 C++自定义Http节点获得Header数据

一、新建C文件 选择All Classes&#xff0c;选择父类BlueprintFunctionLibrary&#xff0c;命名为SendHttpRequest。 添加Http支持 代理回调的参数使用DECLARE_DYNAMIC_DELEGATE_TwoParam定义&#xff0c;第一参数是代理类型&#xff0c;后面是参数1类型&#xff0c;参数1&…