自旋锁 pause版权看源码的时候get的一个新的知识点,可以提升自旋锁spinlock的性能-pause指令,看到的源码如下:
define UT_RELAX_CPU() asm (“pause” )
define UT_RELAX_CPU() asm volatile (“pause”)
经过上网查找资料pause指令。当spinlock执行lock()获得锁失败后会进行busy loop,不断检测锁状态,尝试获得锁。这么做有一个缺陷:频繁的检测会让流水线上充满了读操作。另外一个线程往流水线上丢入一个锁变量写操作的时候,必须对流水线进行重排,因为CPU必须保证所有读操作读到正确的值。流水线重排十分耗时,影响lock()的性能。
自旋锁spinlock剖析与改进Pause指令解释(from intel):Description Improves the performance of spin-wait loops. When executing a “spin-wait loop,” a Pentium 4 or Intel Xeon processor suffers a severe performance penalty when exiting the loop because it detects a possible memory order violation. The PAUSE instruction provides a hint to the processor that the code sequence is a spin-wait loop. The processor uses this hint to avoid the memory order violation in most situations, which greatly improves processor performance. For this reason, it is recommended that a PAUSE instruction be placed in all spin-wait loops.
MySQL spin lock处理代码
===================
MySQL关于spin lock的部分代码。如下代码可以看到MySQL默认作了30次(innodb_sync_spin_loops=30)mutex检查后,才放弃占用CPU资源。
rw_lock_sx_lock_func( // 加sx锁函数
{
/* Spin waiting for the lock_word to become free */
os_rmb;
while (i < srv_n_spin_wait_rounds
&& lock->lock_word <= X_LOCK_HALF_DECR) {
if (srv_spin_wait_delay) {
ut_delay(ut_rnd_interval(
0, srv_spin_wait_delay)); // 加锁失败,调用ut_delay
}
i++;
}
spin_count += i;
if (i >= srv_n_spin_wait_rounds) {
os_thread_yield(); //暂停当前正在执行的线程对象(及放弃当前拥有的cup资源)
} else {
goto lock_loop; //MySQL关于spin lock的部分代码。如下代码可以看到MySQL默认作了30次(innodb_sync_spin_loops=30)mutex检查后,才放弃占用CPU资源。
os_thread_yield(); //暂停当前正在执行的线程对象(及放弃当前拥有的cup资源)
}
…
ulong srv_n_spin_wait_rounds = 30;
ulong srv_spin_wait_delay = 6;
注:上面代码,线程中的yield()方法说明
yield 多线程版权Thread.yield()方法作用是:暂停当前正在执行的线程对象(及放弃当前拥有的cup资源),并执行其他线程。yield()做的是让当前运行线程回到可运行状态,以允许具有相同优先级的其他线程获得运行机会。因此,使用yield()的目的是让相同优先级的线程之间能适当的轮转执行。
每次ut_delay默认执行pause指令300次( innodb_spin_wait_delay=6*50)
ut_delay(
/=====/
ulint delay) /*!< in: delay in microseconds on 100 MHz Pentium */
{
ulint i, j;
UT_LOW_PRIORITY_CPU();
j = 0;
for (i = 0; i < delay * 50; i++) {
j += i;
UT_RELAX_CPU();
}
UT_RESUME_PRIORITY_CPU();
return(j);
}
define UT_RELAX_CPU() asm (“pause” )
define UT_RELAX_CPU() asm volatile (“pause”)
操作系统中,SYS和USER这两个不同的利用率代表着什么?
操作系统中,SYS和USER这两个不同的利用率代表着什么?或者说二者有什么区别?
简单来说,CPU利用率中的SYS部分,指的是操作系统内核(Kernel)使用的CPU部分,也就是运行在内核态的代码所消耗的CPU,最常见的就是系统调用(SYS CALL)时消耗的CPU。而USER部分则是应用软件自己的代码使用的CPU部分,也就是运行在用户态的代码所消耗的CPU。比如ORACLE在执行SQL时,从磁盘读数据到db buffer cache,需要发起read调用,这个read调用主要是由操作系统内核包括设备驱动程序的代码在运行,因此消耗CPU计算到SYS部分;而ORACLE在解析从磁盘中读到的数据时,则只是ORACLE自己的代码在运行,因此消耗的CPU计算到USER部分。
那么SYS部分的CPU主要会由哪些操作或是系统调用产生呢?具体如下所示。
1> I/O操作。比如读写文件、访问外设、通过网络传输数据等。这部分操作一般不会消耗太多的CPU,因为主要的时间消耗会在1/O操作的设备上。比如从磁盘读文件时,主要的时间在磁盘内部的操作上,而消耗的CPU时间只占I/O操作响应时间的一少部分。只有在过高的并发I/O时才可能会使得SYS CPU 有所增加。
2> 内存管理。比如应用程序向操作系统申请内存,操作系统维护系统可用内存,交换空间换页等。其实与ORACLE类似,越大的内存,越频繁的内存管理操作,CPU的消耗会越高。
3> 进程调度。这部分CPU的使用,在于操作系统中运行队列的长短,越长的运行队列,表明越多的进程需要调度,那么内核的负担就越高。
4> 其他,包括进程间通信、信号量处理、设备驱动程序内部的一些活动等等。
什么是用户态?什么是内核态?如何区分?
一般现代CPU都有几种不同的指令执行级别。
在高执行级别下,代码可以执行特权指令,访问任意的物理地址,这种CPU执行级别就对应着内核态。
而在相应的低级别执行状态下,代码的掌控范围会受到限制。只能在对应级别允许的范围内活动。
举例:
intel x86 CPU有四种不同的执行级别0-3,linux只使用了其中的0级和3级分别来表示内核态和用户态。
系统调用与context switch
进程上下文切换,是指从一个进程切换到另一个进程运行。而系统调用过程中一直是同一个进程在运行
系统调用过程通常称为特权模式切换,而不是上下文切换。当进程调用系统调用或者发生中断时,CPU从用户模式(用户态)切换成内核模式(内核态),此时,无论是系统调用程序还是中断服务程序,都处于当前进程的上下文中,并没有发生进程上下文切换。
当系统调用或中断处理程序返回时,CPU要从内核模式切换回用户模式,此时会执行操作系统的调用程序。如果发现就需队列中有比当前进程更高的优先级的进程,则会发生进程切换:当前进程信息被保存,切换到就绪队列中的那个高优先级进程;否则,直接返回当前进程的用户模式,不会发生上下文切换。
system call
System calls in most Unix-like systems are processed in kernel mode, which is accomplished by changing the processor execution mode to a more privileged one, but no process context switch is necessary
context switch
Some operating systems(Not include Linux) also require a context switch to move between user mode and kernel mode tasks. The process of context switching can have a negative impact on system performance
通过vmstat查看context switch
一般vmstat工具的使用是通过两个数字参数来完成的,第一个参数是采样的时间间隔数,单位是秒,第二个参数是采样的次数,如:
root@local:~# vmstat 2 1
procs -----------memory---------- —swap-- -----io---- -system-- ----cpu----
r b swpd free buff cache si so bi bo in cs us sy id wa
1 0 0 3498472 315836 3819540 0 0 0 1 2 0 0 0 100 0
context switch 高,导致的争用其它案例
有很多种情况都会导致 context switch。MySQL 中的 mutex 和 RWlock 在获取不成功后,短暂spin,还不成功,就会发生 context switch,sleep,等待唤醒。
在 MySQL中,mutex 和 RWlock导致的 context switch,一般在show global status,show engine innodb mutex,show engine innodb status,performance_schema等中会体现出来,针对不同的mutex和RWlock等待,可以采取不同的优化措施。
除了MySQL的mutex和RWlock,还发现一种情况,是MySQL外的mutex竞争导致context switch高。
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
最后
码字不易,觉得有帮助的可以帮忙点个赞,让更多有需要的人看到
又是一年求职季,在这里,我为各位准备了一套Java程序员精选高频面试笔试真题,来帮助大家攻下BAT的offer,题目范围从初级的Java基础到高级的分布式架构等等一系列的面试题和答案,用于给大家作为参考
以下是部分内容截图
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
点个赞,让更多有需要的人看到**
又是一年求职季,在这里,我为各位准备了一套Java程序员精选高频面试笔试真题,来帮助大家攻下BAT的offer,题目范围从初级的Java基础到高级的分布式架构等等一系列的面试题和答案,用于给大家作为参考
以下是部分内容截图
[外链图片转存中…(img-ERdeKsP1-1712984002653)]
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!