1.1.1.多線程的發展--對cpu性能的壓榨史

一.壓榨歷史

1.單進程人工切換。紙帶機。只能解決簡單的數學問題。

2.單道批處理。多進程批處理。多個任務批量執行。解決手動操作時需要人工切換作業導致的系統利用率低的問題

3.多進程并行處理。把程序寫在不同的內存位置來回切換。當一個作業在等待I/O處理時,多批處理系統會通過相應調度算法調度另外一個作業讓計算機執行

4.多線程。一個程序內部不同任務的來回切換。實現進程中任務的切換,又可以避免進程切換內存地址空間(將計算機實際調度的單元轉到線程)。

5.纖程/協程與管程

二.相關含義介紹

什么是程序?什么是進程?什么是進程?什么是纖程/協程、管程?

1.程序-->抽象概念

操作系統可以執行的一個計算機文件。是一組計算機能識別和執行的指令序列。如QQ.exe

2.進程-->靜態概念

進程是程序計算機(內存)中的一次運行活動。更通俗一點來說:進程是程序的實例化(類似于程序是class,進程是class的對象)。

進程是系統進行資源分配的基本單位,進程是線程的容器。

3.線程-->動態概念

一條線程指的是進程中一個單一順序的執行路線(也可以說是執行流、控制流)。即進程中的實際運行單位。

資源調度的基本單位。

4.線程上下文

線程上下文是指某一時間點 CPU 寄存器和程序計數器的內容。

4.1.使用場景

上下文切換 (context switch) 。即任務切換, 或者CPU寄存器切換。

當多任務內核決定運行另外的任務時, 它保存正在運行任務的當前狀態, 也就是CPU寄存器中的全部內容。這些內容被保存在任務自己的堆棧中, 入棧工作完成后就把下一個將要運行的任務的當前狀況從該任務的棧中重新裝入CPU寄存器, 并開始下一個任務的運行, 這一過程就是context switch。

4.2.上下文切換帶來的問題

程序執行效率與線程并發數,從正相關變為負相關;

三.思考問題

1.單核的CPU設定多線程是否有意義?

其實個人的觀點是,需要分析多線程的本質-->是對cpu性能的壓榨。

那么,如果說單線程已經達到非常好的cpu利用率,則使用多線程意義不是太大。這種作業就稱為cpu密集型(性能瓶頸是CPU運算)。

相對的,將性能瓶頸是IO(網絡通信、硬盤讀寫、阻塞等待等)的作業稱為io密集型。因為這種作業會造成cpu空閑,而使用多線程可顯著減少此情況。

2.工作線程數是不是設置得越大越好?

a.先看一個示例:
package com.pavin.thread;
?
import java.text.DecimalFormat;
import java.util.Random;
import java.util.concurrent.CountDownLatch;
?
public class multiThread_01 {
?private static double[] nums = new double[1_0000_0000];private static Random r = new Random();private static DecimalFormat df = new DecimalFormat("0.00");static {for (int j = 0; j < nums.length; j++) {nums[j] = r.nextDouble();}}
?private static void singleThread() {long start = System.currentTimeMillis();
?double result = 0.0;for (int j = 0; j < nums.length; j++) {result += nums[j];}
?long end = System.currentTimeMillis();System.out.println("1 ? " + " singleThread: cost " + (end-start) + "ms result: " + df.format(result));}
?static double result1 = 0.0, result2 = 0.0, result3 = 0.0;private static void twoThreads() throws InterruptedException {
?Thread t1 = new Thread(() -> {for (int j = 0; j < nums.length / 2; j++) {result1 += nums[j];}});
?Thread t2 = new Thread(() -> {for (int j = nums.length / 2; j < nums.length; j++) {result2 += nums[j];}});
?long start = System.currentTimeMillis();t1.start();t2.start();t1.join();t2.join();
?result3 = result1 + result2;long end = System.currentTimeMillis();System.out.println("2 ? " + " Threads: cost " + (end-start) + "ms result: " + df.format(result3));}
?private static void multiThreads(int threadCount) throws InterruptedException {
?Thread[] threads = new Thread[threadCount];double[] results = new double[threadCount];final int segmentCount = nums.length / threadCount;CountDownLatch latch = new CountDownLatch(threadCount);
?for (int i = 0; i < threadCount; i++) {int m = i;
?threads[i] = new Thread(() -> {for (int j = m * segmentCount; j < (m+1) * segmentCount && j < nums.length; j++) {results[m] += nums[j];}});
?latch.countDown();}
?double result = 0.0;long start = System.currentTimeMillis();for (Thread t : threads) {t.start();}
?latch.await();for (double v : results) {result += v;}
?long end = System.currentTimeMillis();System.out.println(threadCount + " Threads: cost " + (end-start) + "ms result: " + df.format(result));}
?public static void main(String[] args) throws InterruptedException {singleThread();twoThreads();
?multiThreads(10000);}
}

輸出結果:

1 ? ?singleThread: cost 134ms result: 49997084.08
2 ? ?Threads: cost 78ms result: 49997084.08
10000 Threads: cost 1012ms result: 49997084.08

由此可見,使用兩個線程時明顯比一個線程更快,但是使用10000個線程時,非常慢。所以線程并不是越大越好。

b.造成效率下降的原因

見線程上下文

3.工作線程數(線程池中的線程數量)設置為多少合適?

公式+壓測

a.公式

CPU密集型:理論上線程的數量=CPU核數最合適。

不過實際中一般會設為CPU核數+1。此時當線程因為偶爾的內存頁失效或其他原因導致阻塞時,這個額外的線程可以頂上,從而保證CPU的利用率

IO密集型 :線程數 = CPU核心數 * 目標CPU利用率 *(1+平均等待時間/平均工作時間)

b.實際中的問題
i.環境開銷

比如一個普通的SpringBoot 為基礎的業務系統,默認Tomcat容器+HikariCP連接池+G1回收器。

Tomcat有自己的線程池,HikariCP也有自己的后臺線程,JVM也有一些編譯的線程,連G1都有自己的后臺線程。這些線程也是運行在當前進程、當前主機上的,也會占用CPU的資源。

ii.測算"平均等待時間"、“平均工作時間”

方法1,通過日志和統計的方式得出。

方法2,第三方工具:profiler/Jprofiler

c.實際策略

一般情況下,內部業務系統相對于性能,更注重穩定好用、符合需求。實際生產推薦的線程數:CPU核心數+1

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/210349.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/210349.shtml
英文地址,請注明出處:http://en.pswp.cn/news/210349.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C語言-函數STRCPY

strcpy char *strcpy(char *restrict dst, const char *restrict src);把src的字符串拷貝到dst restrict表明src和dst不重疊&#xff08;C99&#xff09; 返回dst 為了能鏈起代碼來 復制一個字符串 char dst (char)malloc(strlen(src) 1); strcpy(dst, src);

從單向鏈表中刪除指定值的節點

輸入一個單向鏈表和一個節點的值&#xff0c;從單向鏈表中刪除等于該值的節點&#xff0c;刪除后如果鏈表中無節點則返回空指針。 鏈表的值不能重復。構造過程&#xff0c;例如輸入一行數據為:6 2 1 2 3 2 5 1 4 5 7 2 2則第一個參數6表示輸入總共6個節點&#xff0c;第二個參數…

通過仿真理解完整的陣列信號噪聲模型

概要 噪聲對無線電設備的信號接收會造成影響,是通信、雷達、導航、遙感等工程應用領域中的關鍵考慮因素。通常認為陣列合成能夠提升信噪比,但忽略了這一論斷的前提,即不同通道引入的噪聲互不相關。但實際應用中,接收的噪聲不僅僅包含信道引入的不相關噪聲,還包含從外界環…

1-6、編程語言排行榜

語雀原文鏈接 https://www.tiobe.com/tiobe-index/

IntelliJ IDEA創建一個Maven項目

在IDEA中創建Maven項目&#xff0c;前提是已經安裝配置好Maven環境 。 本文主要使用的是IntelliJ IDEA 2022.2.1 (Community Edition) 1.創建一個新project:File>Project 2.修改Maven配置&#xff1a;File>Settings>搜索maven 創建好的工程如下&#xff1a; src/main…

使用NanoPi NEO4進行rtsp拉流

使用系統&#xff1a;FriendlyDesktop系統 使用python進行編程&#xff0c;分別使用opencv與ffmpeg進行功能實現&#xff0c;折騰了挺長時間&#xff0c;代碼很簡單&#xff0c;主要是環境搭建。主要是python、opencv-python、ffmpeg-python、numpy之間的版本兼容&#xff0c;…

Chart 8 內核優化

文章目錄 前言8.1 內核融合和拆分8.2 編譯選項8.3 Conformant&#xff08;規范&#xff09; vs. fast vs. native math functions8.4 Loop unrolling8.5 避免分支發散8.6 Handle image boundaries8.7 Avoid the use of size_t8.8 通用 vs. 具名內存地址空間8.9 Subgroup8.10 Us…

七個常用<python裝飾器>---足夠改進代碼質量 (保姆詳解)

前言: 寫代碼嘛&#xff0c;關鍵是得讓它既好用又好看&#xff0c;這不&#xff0c;Python裝飾器就擺在那兒。咱們程序員有時也得有那么點藝術家的腔調&#xff1a;講求效率&#xff0c;追求代碼的簡潔優雅&#xff0c;偶爾還得裝裝X&#xff0c;不是嗎&#xff1f; 翻開人家…

SpringSecurity6 | 自定義認證規則

?作者簡介&#xff1a;大家好&#xff0c;我是Leo&#xff0c;熱愛Java后端開發者&#xff0c;一個想要與大家共同進步的男人&#x1f609;&#x1f609; &#x1f34e;個人主頁&#xff1a;Leo的博客 &#x1f49e;當前專欄&#xff1a; Java從入門到精通 ?特色專欄&#xf…

移相干涉技術1-多種干涉條紋仿真模擬生成(原理轉載+代碼實現 包括模擬生成干涉條紋圖)

過去的干涉測量技術是通過人的肉眼或者相機拍攝&#xff0c;來直觀判斷干涉圖中條紋特征進而完成測量&#xff0c;該方法的不穩定因素&#xff08;比如人的主觀意志&#xff09;很多&#xff0c;其精度誤差在/10左右38]&#xff1b;現代干涉測量技術通過將電子技術、計算機技術…

智能優化算法應用:基于廚師算法無線傳感器網絡(WSN)覆蓋優化 - 附代碼

智能優化算法應用&#xff1a;基于廚師算法無線傳感器網絡(WSN)覆蓋優化 - 附代碼 文章目錄 智能優化算法應用&#xff1a;基于廚師算法無線傳感器網絡(WSN)覆蓋優化 - 附代碼1.無線傳感網絡節點模型2.覆蓋數學模型及分析3.廚師算法4.實驗參數設定5.算法結果6.參考文獻7.MATLAB…

代碼隨想錄-刷題第二十一天

530.二叉搜索樹的最小絕對差 題目鏈接&#xff1a;530. 二叉搜索樹的最小絕對差 思路&#xff1a;二叉搜索樹的中序遍歷是有序的。根據二叉搜索樹的這個特性來解題。 class Solution {// 同樣利用二叉樹中序遍歷是一個有序數組。private List<Integer> list new Arra…

一加 12 Pop-up快閃活動來襲,十城聯動火爆開啟

12 月 9 日&#xff0c;一加 12 Pop-up 快閃活動在北京、深圳、上海、廣州等十城聯動開啟&#xff0c;各地加油歡聚快閃現場&#xff0c;搶先體驗與購買一加 12。作為一加十年超越之作&#xff0c;一加 12 全球首發擁有醫療級護眼方案和行業第一 4500nit 峰值亮度的 2K 東方屏、…

C++新經典模板與泛型編程:策略類模板

策略類模板 在前面的博文中&#xff0c;策略類SumPolicy和MinPolicy都是普通的類&#xff0c;其中包含的是一個靜態成員函數模板algorithm()&#xff0c;該函數模板包含兩個類型模板參數。其實&#xff0c;也可以把SumPolicy和MinPolicy類寫成類模板—直接把algorithm()中的兩…

【Linux】無法使用 ifconfig 查看系統網絡接口信息,報錯 command not found: ifconfig

問題描述 ifconfig是一個用于配置和顯示系統網絡接口信息的命令行工具。它通常用于Unix、Linux和其他類Unix系統中。 通過ifconfig命令&#xff0c;你可以查看和修改系統中網絡接口的配置信息&#xff0c;包括IP地址、子網掩碼、MAC地址、MTU&#xff08;最大傳輸單元&#x…

javacv踩坑記錄

前一陣學習opencv&#xff0c;發現在做人臉識別的時候遇到一些類庫不存在的情況&#xff0c;查找后發現是由于拓展包沒有安裝完全&#xff08;僅安裝了基礎版&#xff09;。由于網絡的問題&#xff08;初步猜測&#xff09;&#xff0c;始終無法安裝好拓展包。 于是另辟蹊徑&am…

MongoDb數據庫

一、命令交互 1.1 數據庫命令 1.顯示所有數據庫&#xff1a; show dbs 2.切換到指定數據庫&#xff0c;如果沒有則自動創建數據庫 use databaseName 3.顯示當前所在數據庫 db 4.刪除當前數據庫 use 庫名 db.dropDatabase() 1.2 集合命令 1.創建集合 db.createColl…

[文檔級關系抽取|ACL論文]文檔級關系抽取中語言理解的基礎模型

Did the Models Understand Documents? Benchmarking Models for Language Understanding in Document-Level Relation Extraction School of Computer Science, Fudan University | ACL 2023.06 | 原文鏈接 Background 過去的工作大多數都是從單個句子中收獲更多的關系&am…

MongoDB中的$type操作符和limit與skip方法

本文主要介紹MongoDB中的$type操作符和limit與skip方法。 目錄 MongoDB的$type操作符MongoDB的limit方法MongoDB的skip方法 MongoDB的$type操作符 MongoDB中的$type操作符用于檢查一個字段的類型是否與指定的類型相匹配。它可以用于查詢和投影操作。 $type操作符可以與以下數…

php,redis實現一個電影熱度排行榜

要實現電影熱度排行榜&#xff0c;需要記錄每個電影的熱度值&#xff0c;熱度值可以根據不同的算法計算&#xff0c;例如&#xff1a;觀看次數、評分數、評論數等。這里我們以觀看次數為例。 首先&#xff0c;需要使用 Redis 的 Sorted Set 數據結構來存儲電影的熱度值和電影 …