Java线程亲和实战

环境:Linux version 5.4.0-1084-aws (buildd@lcy02-amd64-044) (gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04)) #91~18.04.1-Ubuntu SMP Sun Aug 14 01:24:43 UTC 2022
JDK: 1.8.0_241

CPU分配是如何工作的?

如果您有或提供了一个,该库将读取您的 /proc/cpuinfo,它将确定您的 CPU 布局。 如果没有,它会假设每个 CPU 都在一个 CPU 插槽上。
该库通过查看默认情况下未运行的 CPU 来查找隔离的 CPU。 即,如果您有 16 个 CPU,但其中 8 个不可用于一般用途(由启动时进程的亲和力决定),它将开始分配给这些 CPU。
注意:如果有多个进程使用该库,则需要指定该进程可以使用哪些 CPU,否则它将为两个进程分配相同的 CPU。 要控制进程可以使用哪些 CPU,请将 -Daffinity.reserved={cpu-mask-in-hex} 添加到进程的命令行。
注意:CPU 0 是为操作系统保留的,它必须在某个地方运行。

服务器配置

配置isolcpus

两种方法:修改/etc/default/grub 中的配置,或添加如下配置之一

  1. GRUB_CMDLINE_LINUX_DEFAULT=“quiet splash isolcpus=1,3”(这里表示1和3两个cpu被隔离,cpu序号从0开始)
  2. GRUB_CMDLINE_LINUX=“isolcpus=1,3”

刷新isolcpus配置

两种方法:更新/boot/grub/grub.cfg文件

方法1
sudo update-grub
  1. 该方法是/etc/default/grub配置文件中第一行注释提供的方法:# If you change this file, run ‘update-grub’ afterwards to update
  2. 如果提示update-grub命令找不到,安装一下:sudo apt-get update; sudo apt-get install --reinstall grub
  3. 查看/boot/grub/grub.cfg文件的时间戳确认是否更新成功
方法2
sudo grub-mkconfig -o /boot/grub/grub.cfg

重启系统

验证配置是否生效

方法1:查看启动参数

查看/proc/cmdline里是不是有isolcpu参数

方法2:查看进程的cpu affinity

例如查看进程1的cpu affinity。服务器位32核,当前没有cpu隔离

taskset -cp 1
### 输出
pid 1's current affinity list: 0-31### 查看当前cpu隔离
taskset -cp $$

输出结果有可能是16进制,例如:ffffffff。也就是没有cpu隔离,二进制对应(32位1):11111111111111111111111111111111
如果cpu5被隔离,那么16进制对应:ffffffef,二进制对应:11111111111111111111111111101111

查看所有进程cpu分配情况

ps -eo 'pid,cmd,psr'

查看所有线程cpu分配情况

ps -To 'pid,lwp,psr,cmd'

irqbalance配置

目的:禁用“隔离cpu”的IRQ,可以减少IRQ中断导致的用户与内核之间的上下文切换。进一步提升性能

IRQ是什么

wiki百科解释

在计算机中,中断请求(或 IRQ)是发送到处理器的硬件信号,该信号暂时停止正在运行的程序并允许特殊程序(中断处理程序)运行。
In a computer, an interrupt request (or IRQ) is a hardware signal sent to the processor that temporarily stops a running program and allows a special program, an interrupt handler, to run instead.

网卡与操作系统的交互一般有两种方式:
IRQ(Interrupt Request 中断请求):网卡在收到了网络信号之后,主动发送中断到CPU。而CPU将会立即停下手边的活以便对这个中断信号进行分析
DMA(Direct Memory Access 直接存储器访问):允许硬件在无 CPU 干预的情况下将数据缓存在指定的内存空间内,在CPU合适的时候才处理

配置

官方文档说明较少
In /etc/sysconfig/irqbalance or /etc/defaults/irqbalance or /etc/default/irqbalance you can set:

IRQBALANCE_BANNED_CPUS=CC

In the case this is not working, turn off irqbalance instead using the following command:

## 关闭IRQ均衡,只在cpu0上进行IRQ。参考:https://serverfault.com/questions/380935/how-to-ban-hardware-interrupts-with-irqbalance-banned-cpus-on-ubuntu
$ sudo chkconfig irqbalance off

serverfault配置案例:

This is a hex mask without the leading ‘0x’, on systems with large numbers of processors each group of eight hex digits is sepearated ba a comma ‘,’. i.e. export IRQBALANCE_BANNED_CPUS=fc0 would prevent irqbalance from assigning irqs to the 7th-12th cpus (cpu6-cpu11) or export IRQBALANCE_BANNED_CPUS=ff000000,00000001 would prevent irqbalance from assigning irqs to the 1st (cpu0) and 57th-64th cpus (cpu56-cpu63).

So, you’d create /etc/default/irqbalance with the contents

ENABLED="1"
ONESHOT="0"
IRQBALANCE_BANNED_CPUS="3f"

To see what is going on, try

$ sudo service irqbalance stop
Stopping SMP IRQ Balancer: irqbalance.
$ source /etc/default/irqbalance 
$ sudo irqbalance --debug
查看interrupts
cat /proc/interrupts

Java代码开发

pom

<dependency><groupId>net.openhft</groupId><artifactId>affinity</artifactId><version>3.23.3</version>
</dependency>

测试案例

单线程

默认按照任意cpu分配

import lombok.SneakyThrows;import lombok.extern.slf4j.Slf4j;import net.openhft.affinity.Affinity;
import net.openhft.affinity.AffinityLock;import java.util.*;@Slf4j
public class ThreadAffinityTest {private static volatile boolean flag = true;@SneakyThrowspublic static void main(String[] args) {test();}@SneakyThrowsprivate static void test() {Thread t = new Thread(() -> {try (final AffinityLock al = AffinityLock.acquireLock()) {while (flag) {// 返回当前线程亲和掩码BitSet bitSet = Affinity.getAffinity();// 返回当前线程IDlong threadId = Affinity.getThreadId();// 返回当前cpuIdint cpuId = Affinity.getCpu();}}});t.start();Thread.sleep(10_000);flag = false;Thread.sleep(1_000);log.info("t : {}", t.getState());}
}

输出日志

[2024-03-30 15:53:29.823][INFO ][Thread-0  ] net.openhft.affinity.AffinityLock - Assigning cpu 7 to Thread[Thread-0,5,main] on thread id 978944
[2024-03-30 15:53:39.339][INFO ][Thread-0  ] net.openhft.affinity.LockInventory - Releasing cpu 7 from Thread[Thread-0,5,main]
[2024-03-30 15:53:40.344][INFO ][main      ] ...ThreadAffinityTest - t : TERMINATED
线程池
Disruptor<BaseEventWrapper> disruptor = new Disruptor<>(BaseEventWrapper::new, 8192,new AffinityThreadFactory("MY-EVENT-HANDLER-EXECUTOR"),ProducerType.MULTI,new BusySpinWaitStrategy());

为进程指定预保留的cpu

这可用于尝试保留 CPU,或者如果您有多个程序需要保留 CPU,这可确保它们不会尝试使用相同的 CPU。

## 不管有没有这个,您都可以使用以下命令设置保留 CPU 的位掩码:
-Daffinity.reserved=cc

申请整个core

注意,该用法会导致超线程空闲
You can reserve a whole core. If you have hyper-threading enabled, this will use one CPU and leave it’s twin CPU unused.

try (AffinityLock al = AffinityLock.acquireCore()) {// do some work while locked to a CPU.
}

控制cpu布局

在此示例中,库将优先选择与第一个线程相同的 Socket(插槽) 上的空闲 CPU,否则它将选择任何空闲 CPU。

try (final AffinityLock al = AffinityLock.acquireLock()) {System.out.println("Main locked");Thread t = new Thread(new Runnable() {@Overridepublic void run() {try (AffinityLock al2 = al.acquireLock(AffinityStrategies.SAME_SOCKET,AffinityStrategies.ANY)) {System.out.println("Thread-0 locked");}}});t.start();
}

API指定cpu执行

调用api:setAffinity

long currentAffinity = AffinitySupport.getAffinity();
Affinity.setAffinity(1L << 5); // lock to CPU 5

参考

https://github.com/OpenHFT/Java-Thread-Affinity?tab=readme-ov-file
https://github.com/peter-lawrey/Java-Thread-Affinity/wiki/Getting-started
https://serverfault.com/questions/380935/how-to-ban-hardware-interrupts-with-irqbalance-banned-cpus-on-ubuntu

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

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

相关文章

sqlmap(五)

一、进行文件读写操作 1.1 前提条件 高权限 目录有读写权限 secure_file_priv " " 1.2 测试目标 第一步&#xff1a;用抓包的方式获取请求测试站点的数据包 可以使用Burpsuite 第二步&#xff1a;将抓到的数据包&#xff0c;保存到sqlmap目录下的a.txt 第三步&am…

FPGA和ARM学习那个比较好

FPGA和ARM是两种不同的技术&#xff0c;具有不同的应用领域和学习难度。以下是对两者进行比较的一些建议&#xff1a; 1. 应用领域&#xff1a;FPGA主要用于数字电路设计和硬件加速器开发&#xff0c;可在实时系统、信号处理、嵌入式系统等方面发挥重要作用。ARM则是一种处理器…

C++的vector类(二):vector类的实际OJ应用

1、只出现一次的数字 2、杨辉三角 3、删除有序数组中的重复项 4、只出现一次的数字 II 5、只出现一次的数字 III 6、数组中出现次数超过一半的数字 7、电话号码的字母组合 ~over~

从FasterTransformer源码解读开始了解大模型(1.1)一个decoder-only的模型长啥样

从FasterTransformer源码解读开始了解大模型&#xff08;1.1&#xff09;一个decoder-only的模型长啥样 写在前面的话 对于一个没有接触过LLM的初学者来说&#xff0c;如果想要了解一个大模型的推理框架&#xff0c;首先应该知道大模型整个的工作原理是怎样的&#xff0c;知道…

了解自动化机器学习 AutoML

&#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ 自动化机器学习&#xff08;AutoML&#xff09;概述 自动化机器学习&#xff08;AutoML&#xff09;旨在自动化机器学习模型的开发流程&#xff0c;通过简化或去除需要专业知识的复杂步骤&#xff0c;…

CSS面试题常用知识总结day03

大家好我是没钱的君子下流坯&#xff0c;用自己的话解释自己的知识 前端行业下坡路&#xff0c;甚至可说前端已死&#xff0c;我还想在前段行业在干下去&#xff0c;所以从新开始储备自己的知识。 从CSS——>Javascript——>VUE2——>Vuex、VueRouter、webpack——>…

Stale Diffusion、Drag Your Noise、PhysReaction、CityGaussian

本文首发于公众号&#xff1a;机器感知 Stale Diffusion、Drag Your Noise、PhysReaction、CityGaussian Drag Your Noise: Interactive Point-based Editing via Diffusion Semantic Propagation Point-based interactive editing serves as an essential tool to compleme…

vite打包失败 - out of memory

在做项目时&#xff0c;随着需求的不断增加&#xff0c;我们的代码文件会越来越大&#xff0c;但是在打包时&#xff0c;在 Node 中通过 JavaScript 使用内存的大小却是有限制的。于是&#xff0c;今天打算部署代码时&#xff0c;报错了: <--- JS stacktrace ---> JS st…

Nuxt 3 项目中配置 Tailwind CSS

官方文档&#xff1a;https://www.tailwindcss.cn/docs/guides/nuxtjs#standard 安装 Tailwind CSS 及其相关依赖 执行如下命令&#xff0c;在 Nuxt 项目中安装 Tailwind CSS 及其相关依赖 npm install -D tailwindcss postcss autoprefixerpnpm install -D tailwindcss post…

VUE必知必会

一、简介 Vue.js是一个流行的JavaScript框架&#xff0c;用于构建用户界面和单页应用程序&#xff08;SPA&#xff09;。自2014年由前Google工程师尤雨溪发布以来&#xff0c;Vue迅速获得了广泛的关注和使用&#xff0c;特别是在前端开发领域。 核心特性 响应式数据绑定&#…

【cpp】快速排序优化

标题&#xff1a;【cpp】快速排序 水墨不写bug 正文开始&#xff1a; 快速排序的局限性&#xff1a; 虽然快速排序是一种高效的排序算法&#xff0c;但也存在一些局限性&#xff1a; 最坏情况下的时间复杂度&#xff1a;如果选择的基准元素不合适&#xff0c;或者数组中存在大…

vue基本写法

<p style"margin-left:.0001pt;text-align:justify;">Vue.js 是一种流行的 JavaScript 框架&#xff0c;用于构建用户界面。下面是 Vue.js 的一些标准写法和最佳实践:</p> 1. Vue 实例&#xff1a; 创建 Vue 实例时&#xff0c;可以指定一些选项来定义应…

Netty 3 - 组件和设计

这里将回顾我们之前章节讲到过的主要概念和组件。 1 Channel 、EventLoop和ChannelFuture Channel —— Socket;EventLoop —— 控制流、多线程处理、并发;ChannelFuture —— 异步通知。 1.1 Channel 接口 基本的I/O操作&#xff08;bind()、connect()、read()和write()&a…

【嵌入式开发 Linux 常用命令系列 4.3 -- git add 不 add untracked file】

请阅读【嵌入式开发学习必备专栏 】 文章目录 git add 不add untracked file git add 不add untracked file 如果你想要Git在执行git add .时不添加未跟踪的文件&#xff08;untracked files&#xff09;&#xff0c;你可以使用以下命令&#xff1a; git add -u这个命令只会加…

boost共享内存使用(3)managed_shared_memory共享内存分配器

文章目录 概述使用示例 概述 Boost.Interprocess提供了一些基本的类来创建共享内存对象和文件映射&#xff0c;并将这些可映射的类映射到进程的地址空间中。 然而&#xff0c;管理这些内存段对于非平凡的任务来说并不容易。一个映射区域是一个固定长度的内存缓冲区&#xff0…

免注册,ChatGPT可即时访问了!

AI又有啥进展&#xff1f;一起看看吧 Apple进军个人家用机器人 Apple在放弃自动驾驶汽车项目并推出混合现实头显后&#xff0c;正在进军个人机器人领域&#xff0c;处于开发家用环境机器人的早期阶段 报告中提到了两种可能的机器人设计。一种是移动机器人&#xff0c;可以跟…

鸿蒙OS元服务开发:【(Stage模型)学习窗口沉浸式能力】

一、体验窗口沉浸式能力说明 在看视频、玩游戏等场景下&#xff0c;用户往往希望隐藏状态栏、导航栏等不必要的系统窗口&#xff0c;从而获得更佳的沉浸式体验。此时可以借助窗口沉浸式能力&#xff08;窗口沉浸式能力都是针对应用主窗口而言的&#xff09;&#xff0c;达到预…

二叉堆解读

在数据结构和算法中&#xff0c;二叉堆是一种非常重要的数据结构&#xff0c;它被广泛用于实现优先队列、堆排序等场景。本文将介绍二叉堆的基本概念、性质、操作以及应用场景。 一、基本概念 二叉堆是一种特殊的完全二叉树&#xff0c;它满足堆性质&#xff1a;对于每个节点…

练习题(2024/4/3)

1题目描述&#xff1a; 给定两个大小分别为 m 和 n 的正序&#xff08;从小到大&#xff09;数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。 算法的时间复杂度应该为 O(log (mn)) 。 示例 1&#xff1a; 输入&#xff1a;nums1 [1,3], nums2 [2] 输出&…

Redis Hash结构操作

基础篇Redis 6.4 Hash结构操作 在基础篇的最后&#xff0c;咱们对Hash结构操作一下&#xff0c;收一个小尾巴&#xff0c;这个代码咱们就不再解释啦 马上就开始新的篇章~~~进入到我们的Redis实战篇 SpringBootTest class RedisStringTests {Autowiredprivate StringRedisTe…