CPU密集型和IO密集型任务的权衡:如何找到最佳平衡点

news/2024/5/14 20:41:15

关于作者:CSDN内容合伙人、技术专家, 从零开始做日活千万级APP。
专注于分享各领域原创系列文章 ,擅长java后端、移动开发、人工智能等,希望大家多多支持。

目录

  • 一、导读
  • 二、概览
  • 三、CPU密集型与IO密集型
    • 3.1、CPU密集型
    • 3.2、I/O密集型
  • 四、如何区分IO密集型、CPU密集型任务
  • 五、 推荐阅读

一、导读

我们继续总结学习Java基础知识,温故知新。

二、概览

CPU密集型与I/O密集型是在计算机上执行任务的两种策略,在并发执行任务场景下,我们需要选择使用多线程或多进程;
如果是IO密集型任务,使用多线程,线程越多越好;
如果是CPU密集型任务,使用多进程,线程数量与CPU核心数匹配。

我们了解这些概念有助于在资源分配和性能优化等方面有很大的帮助。
我们在选择线程池的时候,我们需要知道某一个任务是否是CPU消耗型的任务,还是说IO类型的任务,以便充分的调用CPU资源。

三、CPU密集型与IO密集型

3.1、CPU密集型

CPU密集型,也叫计算密集型
系统运行时,CPU读写I/O(硬盘/内存)时可以在很短的时间内完成,几乎没有阻塞时间(等待I/O的实时间),而CPU一直有大量运算要处理,因此CPU负载长期过高。

CPU密集几乎无I/O阻塞,CPU一直会全速运行。如果是单核情况下,开多线程是没有意义的,一个CPU来回切着运行,增加线程切换的资源消耗。
可见,CPU密集任务只有在多核CPU上、开多线程才可能提速。

CPU使用率较高时(如我们训练算法模型、搞训练集),通常线程数只需要设置为CPU核心数的线程个数就可以了。

一般其计算公式可遵循:CPU密集型核心线程数 = CPU核数 + 1。《Java并发编程实践》这么说:计算密集型的线程恰好在某时因为发生一个页错误或者因其他原因而暂停,刚好有一个“额外”的线程,可以确保在这种情况下CPU周期不会中断工作。

特点:

  • 进行大量的计算
  • 消耗CPU资源,较高的CPU占用率,比如计算圆周率、对视频进行高清解码等等,全靠CPU的运算能力。
  • 较少的IO操作

3.2、I/O密集型

I/O密集型相反,听名字就知道,系统运行多是CPU在等I/O (硬盘/内存) 的读写操作,此类情景下CPU负载并不高。

I/O密集型的程序一般在达到性能极限时,CPU占用率仍然较低。
这可能是因为任务本身需要大量I/O操作,没有充分利用CPU能力,导致线程空余时间很多。
通常我们会开CPU核心数数倍的线程,在线程进行 I/O 操作 CPU 空闲时,启用其他线程继续使用 CPU,以提高 CPU 的使用率,充分利用CPU资源。

一般其计算公式可遵循:I/O密集型核心线程数 = (线程等待时间/ 线程CPU时间 + 1)* CPU数目。当然我们也看到有多种计算公式,但都不是最优解,具体情况需结合项目实际使用,配置合适的线程数

一般来说:文件读写、DB读写、网络请求等都是I/O密集型

特点:

  • 高IO操作
  • 计算操作少
  • CPU占用率低

四、如何区分IO密集型、CPU密集型任务

我们需要知道某一个任务是否是CPU消耗型的任务(定容线程池),还是说IO类型的任务(缓存线程池),充分的调用CPU资源。

那在此之前,我们需要知道两个概念:

Wall Duration:代码执行时间(包括了running + runnable + sleep等所有时长)

比如我们要知道某方法执行时间,可以通过系统时间差即可:

    void method() {long start = System.currentTimeMillis();// 业务代码    long wallTime = System.currentTimeMillis() - start;}

CPU Duration: 代码消耗CUP的时间(重点指标,优化方向)。

    void method() {long start = SystemClock.currentThreadTimeMillis(); //当前线程运行了多少时间(毫秒值,不含thread或systemclock.sleep的值)// 业务代码    long wallTime = SystemClock.currentThreadTimeMillis() - start;}

那如果在Android 端,我们借助SysTrace工具即可(具体方法可自行搜索),如下图
1
通过SysTrace查看 Wall Duration 与 CPU Duration,

消耗的CPU时间片较多,我们就把它定义为CPU消耗型的任务,放在定容线程池里调度(即线程数量固定)

消耗的时间片少,我们就把它定义为IO类型的任务,放在缓存线程池中。

  • 缓存线程池(CachedThreadPool)是Java中的一种线程池类型。它是一种动态线程池,可以根据需要自动创建新的线程,并在线程空闲一段时间后销毁。

以上是比较粗暴的分类方法,如果是混合型的任务,那就要慢慢调试,找个最佳数量。

五、 推荐阅读

Java 专栏

SQL 专栏

数据结构与算法

Android学习专栏


http://www.mrgr.cn/p/43044454

相关文章

【已解决】windows7添加打印机报错:加载Tcp Mib库时的错误,无法加载标准TCP/IP端口的向导页

windows7 添加打印机的时候,输入完打印机的IP地址后,点击下一步,报错: 加载Tcp Mib库时的错误,无法加载标准TCP/IP端口的向导页 解决办法: 复制以下的代码到新建文本文档.txt中,然后修改文本文…

搭建测试平台开发(一):Django基本配置与项目创建

一、安装Django最新版本 1 pip install django 二、创建Django项目 首先进入要存放项目的目录,再执行创建项目的命令 1 django-admin startproject testplatform 三、Django项目目录详解 1 testplatform 2 ├── testplatform  # 项目的容器 3 │ ├──…

清洁机器人规划控制方案

清洁机器人规划控制方案 作者联系方式Forrest709335543qq.com 文章目录 清洁机器人规划控制方案方案简介方案设计模块链路坐标变换算法框架 功能设计定点自主导航固定路线清洁区域覆盖清洁贴边沿墙清洁自主返航回充 仿真测试仿真测试准备定点自主导航测试固定路线清洁测试区域…

ER系列路由器多网段划分设置指南

ER系列路由器多网段划分设置指南 - TP-LINK 服务支持 TP-LINK ER系列路由器支持划分多网段,可以针对不同的LAN接口划分网段,即每一个或多个LAN接口对应一个网段;也可以通过一个LAN接口与支持划分802.1Q VLAN的交换机进行对接,实现…

微信小程序导入微信地址

获取用户收货地址。调起用户编辑收货地址原生界面,并在编辑完成后返回用户选择的地址。 1:原生微信小程序接口使用API:wx.chooseAddress(OBJECT) wx.chooseAddress({success (res) {console.log(res.userName)console.log(res.postalCode)c…

Day02-作业(JavaScriptVue)

作业1&#xff1a;实现5秒之后&#xff0c;当前页面直接跳转到官网首页&#xff08;首页地址&#xff1a;https://www.itcast.cn&#xff09; 提示&#xff1a; 5秒之后&#xff0c;才触发某一个动作 素材&#xff1a; <!DOCTYPE html> <html lang"en"&…

【AGI】Copilot AI编程辅助工具安装教程

1. 基础激活教程 GitHub和OpenAI联合为程序员们送上了编程神器——GitHub Copilot。 但是&#xff0c;Copilot目前不提供公开使用&#xff0c;需要注册账号通过审核&#xff0c;我也提交了申请&#xff1a;这里第一期记录下&#xff0c;开启教程&#xff0c;欢迎大佬们来讨论…

【Linux】更换jdk版本

目录 一、前言二、查看jdk版本号1、项目中的版本号&#xff08;pom.xml&#xff09;2、服务器中的版本号 三、更换jdk版本1、创建java文件夹2、下载并解压JDK安装包①、下载jdk安装包②、移动到创建好的/usr/local/java路径下③、解压jdk安装包 四、删除原来的jdk版本1、删除原…

删除 iptables 中的规则

查看规则编号 要删除 iptables 中的规则&#xff0c;可以使用以下命令&#xff1a; 查看 iptables 中的规则&#xff0c;找到要删除的规则的编号&#xff1a; iptables -L --line-numbers删除指定编号的规则&#xff1a; iptables -D [chain] [rule-number]其中&#xff0c;…

设计模式再探——代理模式

目录 一、背景介绍二、思路&方案三、过程1.代理模式简介2.代理模式的类图3.代理模式代码4.代理模式还可以优化的地方5.代理模式的项目实战&#xff0c;优化后(只加了泛型方式&#xff0c;使用CGLIB的代理) 四、总结五、升华 一、背景介绍 最近在做产品过程中对于日志的统一…

c# 此程序集中已使用了资源标识符

严重性 代码 说明 项目 文件 行 禁止显示状态 错误 CS1508 此程序集中已使用了资源标识符“BMap.NET.WindowsForm.BMapControl.resources” BMap.NET.WindowsForm D:\MySource\Decompile\BMap.NET.WindowsForm\CSC 1 活动 运行程序时&a…

网络安全(黑客)自学笔记

1.网络安全是什么 网络安全可以基于攻击和防御视角来分类&#xff0c;我们经常听到的 “红队”、“渗透测试” 等就是研究攻击技术&#xff0c;而“蓝队”、“安全运营”、“安全运维”则研究防御技术。 2.网络安全市场 一是市场需求量高&#xff1b; 二则是发展相对成熟入门…

【iOS】—— UIKit相关问题

文章目录 UIKit常用的UIKit组件懒加载的优势 CALayer和UIView区别关系 UITableViewUITableView遵循的两个delegate以及必须实现的方法上述四个必须实现方法执行顺序其他方法的执行顺序&#xff1a; UICollectionView和UITableView的区别UICollectionViewFlowLayout和UICollecti…

【Hadoop 01】简介

目录 1 Hadoop 简介 2 下载并配置Hadoop 2.1 修改/etc/profile 2.2 修改hadoop-env.sh 2.3 修改core-site.xml 2.4 修改hdfs-site.xml 2.5 修改mapred-site.xml 2.6 修改yarn-site.xml 2.7 修改workers 2.8 修改start-dfs.sh、stop-dfs.sh 2.9 修改start-yarn.sh、s…

Spring MVC异步上传、跨服务器上传和文件下载

一、异步上传 之前的上传方案&#xff0c;在上传成功后都会跳转页面。而在实际开发中&#xff0c;很多情况下上传后不进行跳转&#xff0c;而是进行页面的局部刷新&#xff0c;比如&#xff1a;上传头像成功后将头像显示在网页中。这时候就需要使用异步文件上传。 1.1 JSP页面 …

Abaqus 导出单元刚度矩阵和全局刚度矩阵

Abaqus 导出单元刚度矩阵和全局刚度矩阵 首次创建&#xff1a;2023.7.29 最后更新&#xff1a;2023.7.29 如有什么改进的地方&#xff0c;欢迎大家讨论&#xff01; 详细情况请查阅&#xff1a;Abaqus Analysis User’s Guide 一、Abaqus 导出单元刚度矩阵 1.生成单元刚度矩阵…

DevOps-Jenkins

Jenkins Jenkins是一个可扩展的持续集成引擎&#xff0c;是一个开源软件项目&#xff0c;旨在提供一个开放易用的软件平台&#xff0c;使软件的持续集成变成可能。 官网 应用场景 场景一 研发人员上传开发好的代码到github代码仓库需要将代码下载nginx服务器部署手动下载再…

Android 测试

工程目录图 1- Espresso 2- uiautomator Espresso 文档UI Automator文档ui-automator 英文文档 请点击下面工程名称&#xff0c;跳转到代码的仓库页面&#xff0c;将工程 下载下来 Demo Code 里有详细的注释 代码&#xff1a;testespresso 参考文献 Android 利用 espre…

jsonp劫持

jsonp劫持 什么是jsonjson语法规则浏览器的同源策略JSONPJSONP跨域请求的原理JSONP 的组成深入研究 JSONP劫持漏洞的学习JSONP劫持的原理漏洞利用过程 jsonp劫持举例 什么是json JSON指的是JavaScript对象表示法&#xff08; &#xfeff;JavaScript Object Notation&#xff…

Spring,SpringBoot,Spring MVC的区别是什么

1.Spring是什么 我们通常所说的 Spring 指的是 Spring Framework&#xff08;Spring 框架&#xff09;&#xff0c;它是⼀个开源框架&#xff0c;有着活跃⽽庞⼤的社区&#xff0c;这就是它之所以能⻓久不衰的原因。Spring ⽀持⼴泛的应⽤场景&#xff0c;它可以让 Java 企业级…