CPU密集型和IO密集型与CPU内核之间的关系

CPU密集型和IO密集型与CPU内核之间的关系

一、CPU密集型

  1. 介绍

    CPU密集型,也叫计算密集型,是指需要大量CPU计算资源,例如大量的数学运算、图像处理、加密解密等。这种类型的任务主要依赖于CPU的计算能力,会占用大量的CPU时间片,使得CPU内核在执行任务时负载较重。CPU密集型任务在执行过程中主要消耗CPU资源,而对IO操作的需求相对较少。

  2. 与CPU内核的关系

    CPU密集型任务与CPU内核之间的关系在于任务的执行方式和CPU资源的利用。CPU密集型任务需要大量的CPU计算资源,通常会占用大量的CPU时间片,使得CPU内核在执行任务时负载较重。在多核处理器系统中,如果任务可以充分利用所有的CPU内核,那么整体的计算性能会得到提升。

    在自定义线程池中可以设置 核心线程数=CPU内核数+1,在处理CPU密集型任务时,通常希望充分利用系统中的所有CPU内核,同时避免线程频繁地创建和销毁带来的开销。根据经验,将核心线程数设置为CPU核数加1可以在大多数情况下达到比较好的性能表现。

    设置核心线程数为CPU核数加1的原因是为了确保在系统负载较重的情况下,仍然有一个空闲的线程可以立即执行任务,从而避免因线程创建和销毁带来的性能损失。这样可以更好地利用系统的计算资源,提高CPU密集型任务的执行效率。

  3. 代码测试

    public class CPUAndIOTest {public static void main(String[] args) {int availableProcessors = Runtime.getRuntime().availableProcessors();System.out.println("CPU内核数:" + availableProcessors);// 测试CPU密集型任务testCPUIntensiveTask(availableProcessors);}private static void testCPUIntensiveTask(int availableProcessors){long startTime = System.currentTimeMillis();int taskCount = 100; // 任务数量int corePoolSize = availableProcessors + 1;ExecutorService executor = Executors.newFixedThreadPool(corePoolSize);for (int i = 0; i < corePoolSize; i++) {try {Thread.sleep(50);} catch (InterruptedException e) {throw new RuntimeException(e);}executor.execute(() -> {// 模拟CPU密集型任务double result = 0;for (int j = 0; j < taskCount/corePoolSize; j++) {try {Thread.sleep(50);} catch (InterruptedException e) {throw new RuntimeException(e);}result += Math.random();}});}executor.shutdown();while (!executor.isTerminated()) {}long endTime = System.currentTimeMillis();System.out.println("CPU密集型任务执行时间:" + (endTime - startTime) + "ms");}
    }
    

    模拟执行总量相同的CPU密集型任务,通过修改核心线程数,看看执行时间是多少,得出的结果如下

    核心线程数corePoolSize = 1时

    image-20231207210345776

    核心线程数corePoolSize = availableProcessors + 1也就是CPU内核数加1时

    image-20231207210448524

    核心线程数corePoolSize = availableProcessors * 2也就是CPU内核数*2时

    image-20231207210537937

    结果差不多如预期一样,当核心线程数=CPU内核数加1时执行时间要比另外2种更短,效率更高。

二、IO密集型

  1. 介绍

    IO密集型,是指需要大量的IO操作,例如文件读写、网络通信、数据库访问等。这种类型的任务主要涉及大量的IO操作,而CPU的计算能力相对较少。在执行IO密集型任务时,CPU内核的负载相对较轻,因为大部分时间都用于等待IO操作完成。IO密集型任务的性能瓶颈通常在于IO操作的速度和延迟,而不是CPU的计算能力。

  2. 与CPU内核的关系

    IO密集型任务与CPU内核之间的关系在于任务的执行方式和对系统资源的需求。IO密集型任务通常需要大量的IO操作,例如文件读写、网络通信、数据库访问等,而对CPU计算资源的需求相对较少。

    在自定义线程池中可以设置 核心线程数=CPU内核数*2,在处理IO密集型任务时,通常会出现大量的IO等待时间,而不是CPU计算时间。在这种情况下,可以充分利用系统中的多个CPU内核来处理其他线程的计算任务,从而提高系统的整体性能。

    将核心线程数设置为CPU核数的两倍的原因是为了确保在执行IO密集型任务时,系统能够充分利用CPU内核来处理其他线程的计算任务,同时保持足够的线程数量来处理IO操作。这样可以更好地利用系统的资源,提高IO密集型任务的执行效率。

  3. 代码测试

    public class CPUAndIOTest {public static void main(String[] args) {int availableProcessors = Runtime.getRuntime().availableProcessors();System.out.println("CPU内核数:" + availableProcessors);// 测试IO密集型任务testIOIntensiveTask(availableProcessors);}private static void testIOIntensiveTask(int availableProcessors) {long startTime = System.currentTimeMillis();int corePoolSize = availableProcessors * 2;ExecutorService executor = Executors.newFixedThreadPool(corePoolSize);for (int i = 0; i < corePoolSize; i++) {executor.execute(() -> {// 模拟IO密集型任务try {Thread.sleep(5000/corePoolSize);} catch (InterruptedException e) {e.printStackTrace();}});}executor.shutdown();while (!executor.isTerminated()) {}long endTime = System.currentTimeMillis();System.out.println("IO密集型任务执行时间:" + (endTime - startTime) + "ms");}
    }
    

    结果如下

    核心线程数corePoolSize = 1时

    image-20231207211624930

    核心线程数corePoolSize = availableProcessors + 1也就是CPU内核数加1时

    image-20231207211638205

    核心线程数corePoolSize = availableProcessors * 2也就是CPU内核数*2时

    image-20231207211648650

从以上的结果可以看出,随着线程数的增加,IO密集型任务执行时间会逐渐变短,但线程过多也会导致线程的大量切换,造成资源的浪费,所以一般IO密集型任务设置的核心线程数为CPU内核数*2。

三、总结

  1. CPU密集型:

    核心线程数=CPU内核数+1

  2. IO密集型:

    核心线程数=CPU内核数*2

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

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

相关文章

vcomp140.dll文件丢失解决方法分享:三种亲测有效方案

在计算机使用过程中&#xff0c;我们经常会遇到一些错误提示&#xff0c;其中之一就是“vcomp140.dll丢失”。这个错误提示通常出现在运行某些程序或游戏时&#xff0c;给使用者带来了很大的困扰。那么&#xff0c;vcomp140.dll丢失怎样修复呢&#xff1f;本文将详细介绍解决这…

网工内推 | 国企网工、运维,厂商认证优先,13薪,带薪年假

01 中百集团 招聘岗位&#xff1a;运维工程师 职责描述&#xff1a; 1、对集团内使用云计算架构&#xff08;Kubernetes&#xff09;的系统进行规划、运维及管理相关工作。 2、对集团数据中心系统的大数据基础架构&#xff08;Cloudera Distribution Hadoop&#xff09;的规划…

打补丁,生成.diff文件

作者&#xff1a;爱塔居 文章目录 目录 前言 步骤 一、在根目录上&#xff0c;输入添加指令 二、输入修改内容指令 三、生成补丁 前言 自己的理解&#xff0c;仅供参考&#xff0c;欢迎指正。 补丁的话&#xff0c;在我看来就是方便评审&#xff0c;更方便看修改代码吧。 步骤…

Python-关系运算符详解

关系运算符&#xff1a;比较两个操作数的大小或者相等关系 < > ! 1、关系运算符的关系表达式返回值是布尔类型bool 成立就是真&#xff0c;即1&#xff1b;不成立就是假&#xff0c;即0 2、关系运算符还可以比较字符 字符根据字典序比较&#xff0c;先看首字母在…

智能优化算法应用:基于人工大猩猩部队算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于人工大猩猩部队算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于人工大猩猩部队算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.人工大猩猩部队算法4.实验参数设…

Unity Meta Quest 一体机开发(九):【手势追踪】通过录制抓取手势实现自定义抓取姿势

文章目录 &#x1f4d5;教程说明&#x1f4d5;录制前的准备&#x1f4d5;第一种录制方法&#xff08;Hand Grab Pose Tool 场景&#xff09;⭐在运行模式中确认录制⭐保存录制的手势&#xff0c;将物体做成 Prefab⭐在编辑阶段调整抓取手势&#x1f50d;Fingers Freedom&#x…

德国进口高速主轴电机在机器人上的应用及选型方案

随着机器人技术的日新月异&#xff0c;高速主轴电机在机器人领域的应用也日趋广泛。德国进口的SycoTec高速主轴电机&#xff0c;以其高转速、高精度、高刚度的特点&#xff0c;在机器人的切割、铣削、钻孔、去毛刺等加工应用中发挥着关键作用。 一、高速主轴电机的特点 SycoT…

微信机器人接口开发

简要描述&#xff1a; 设置http回调地址 请求URL&#xff1a; http://域名地址/setHttpCallbackUrl POST 请求头Headers:&#xff08;别忘了传&#xff09; Content-Type&#xff1a;application/jsonAuthorization&#xff1a;login接口返回 参数&#xff1a; 参数名必…

了解Linux网络配置

本章主要介绍网络配置的方法。 网络基础知识 查看网络信息 图形化界面修改 通过配置文件修改 命令行管理 11.1 网络基础知识 一台主机需要配置必要的网络信息&#xff0c;才可以连接到互联网。需要的配置网络信息包括IP、 子网掩码、网关和 DNS。 11.1.1 IP 地址 在计算机…

1.10 C语言之外部变量与作用域

1.10 C语言之外部变量与作用域 一、外部变量概述二、练习 一、外部变量概述 我们说&#xff0c;函数&#xff08;不管是main函数还是其他函数&#xff09;内部定义的变量&#xff0c;其作用范围都只在函数内部&#xff0c;我们把这些变量叫做自动变量或者局部变量。除了局部变…

嵌入式工程师校招经验与学习路线总结

前言&#xff1a;不知不觉2023年秋招已经结束&#xff0c;作者本人侥幸于秋招中斩获数十份大差不差的OFFER&#xff0c;包含&#xff1a;Top级的AIGC&#xff0c;工控龙头&#xff0c;国产MCU原厂&#xff0c;医疗器械&#xff0c;新能源车企等。总而言之&#xff0c;秋招总体情…

HarmonyOS开发工具DevEco Studio的下载和安装

一、DevEco Studio概述 一、下载安装鸿蒙应用开发工具DevEco Studio 开发鸿蒙应用可以从鸿蒙系统上运行第一个程序Hello World开始。 为了得到这个Hello World&#xff0c;你需要得到这个Hello World的源代码&#xff0c;源代码是用人比较容易看得懂的计算机编程语言规范写的…

leetcode做题笔记1466. 重新规划路线

n 座城市&#xff0c;从 0 到 n-1 编号&#xff0c;其间共有 n-1 条路线。因此&#xff0c;要想在两座不同城市之间旅行只有唯一一条路线可供选择&#xff08;路线网形成一颗树&#xff09;。去年&#xff0c;交通运输部决定重新规划路线&#xff0c;以改变交通拥堵的状况。 路…

排序:直接选择排序

直接选择排序&#xff1a; 本质&#xff1a; 直接选择排序的本质就是在数组中进行遍历挑选出最大的元素&#xff0c;讲最大的元素放到对应的位置后&#xff0c;再次选出次大的位置&#xff0c;而后又放到对应的位置..........................直到数组成为一个有序序列。 优…

Leetcode刷题笔记题解(C++):LCR 121. 寻找目标值 - 二维数组

思路&#xff1a;从左小角或者右上角开始遍历&#xff0c;假设右上角开始遍历&#xff0c;如果当前值大于目标值则列-1&#xff1b;如果当前值小于目标值则行1&#xff0c;以此遍历来查找目标值&#xff1b;注意col和row的选取 class Solution { public:bool findTargetIn2DPl…

异常检测 | 基于孤立森林(Isolation Forest)的数据异常数据检测(结合t-SNE降维可视化)

异常检测 | MATLAB实现基于孤立森林的数据异常检测 目录 异常检测 | MATLAB实现基于孤立森林的数据异常检测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 Matlab实现基于孤立森林(Isolation Forest)的数据异常数据检测可视化&#xff08;完整源码和数据) 基于孤立森林(…

状态机的练习:按键控制led灯

设计思路&#xff1a; 三个按键控制led输出。 三个按键经过滤波(消抖)&#xff0c;产生三个按键标志信号。 三个led数据的产生模块&#xff08;流水&#xff0c;跑马&#xff0c;闪烁模块&#xff09;&#xff0c;分别产生led信号。 这六路信号&#xff08;三路按键信号&am…

SpringBoot 注入RedisTemplat 启动报错

需求 因为需要限制部门内多个人员同一时间操作同一批客户的需求&#xff0c;考虑下决定用Redis滑动窗口实现自过期以及并发校验。 问题 新建了个Redis工具类封装RedisTemplat 操作&#xff0c;到启动时却发现无法正常启动&#xff0c;报错注入错误。 The injection point has…

SpringBoot集成系列--ElasticJob

文章目录 一、集成步骤1、添加 ElasticJob 的依赖2、配置 ElasticJob3、定义Job 二、ElasticJob-UI三、Elastic-Job分片理解四、原理 一、集成步骤 1、添加 ElasticJob 的依赖 引入相关依赖到pom.xml <!-- Elastic-Job --> <dependency><groupId>org.apac…

Liunx Centos 防火墙操作

liunx centos 防火墙 查看防火墙状态 systemctl status firewalld查看已经开放的端口 firewall-cmd --list-ports添加端口3306 firewall-cmd --zonepublic --add-port3306/tcp --permanent重启防火墙 firewall-cmd --reload数据库开放账号可以外网登陆 mysql -u root -p …